Skip to content

Ordinary file descriptors leak into POSIX child processes #216

Closed

Description

@dimensionscape

An ordinary file opened through sys.io.File remains open in a POSIX child launched through sys.io.Process, even though it was not selected as any child standard stream.

Regression coverage first: test/regression/ProcessFileInheritance, using Main.hx/build.hxml/stdout.txt. The parent opens a marker file and launches a copy of the test executable. On Linux, the child inspects /proc/self/fd and checks whether any descriptor points to that marker. The parent keeps its file open until the child finishes, then closes it and removes the marker.

Confirmed on Linux x86_64 with Haxe 4.3.3 against checkout 03a4e8d, with the unrelated process reaper work present:

unrelated file inherited: true

Expected: false. Only explicitly selected child standard streams should pass through the normal Process API. The current API offers no way to request inheritance of this ordinary file.

src/hx/libs/std/File.cpp opens files with fopen and does not set close-on-exec. The POSIX Process.cpp child remaps its three pipe endpoints and execs without closing unrelated inherited descriptors. Socket.cpp already creates Linux sockets with SOCK_CLOEXEC and accepts with accept4(..., SOCK_CLOEXEC), so ordinary files are inconsistent with the socket handling.

A long-lived child retains the underlying file after the parent closes it. An unlinked temporary or output file can therefore keep consuming storage until that child exits. For descriptors sharing an open file description, inherited access can also affect the shared offset. Those are consequences of descriptor inheritance; the regression above checks inheritance directly rather than attempting to measure disk retention.

Open runtime-owned files with close-on-exec atomically where the platform supports it. Audit the temporary fopen paths in file_contents and file_contents_bytes too, since another thread can spawn while those reads are active. A later fcntl alone leaves a concurrent-spawn window. If deliberate descriptor inheritance is needed, make it explicit rather than a side effect of every file open.

The reproduction is Linux-only. Windows process creation already uses a handle allowlist when available, so this report does not claim the same reproduction there. No runtime implementation changes are included.

Activity

  1. added a commit that references this issue on Oct 20, 2026
    1da7972
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions