rfcs icon indicating copy to clipboard operation
rfcs copied to clipboard

`std::process`: Close all file descriptors not explicitly passed

Open DemiMarie opened this issue 3 months ago • 3 comments

There are libraries, such as wlroots and GLib, that do not atomically set O_CLOEXEC on the file descriptors they create. Instead, they require any program using the library to close every file descriptor between fork() and exec(), except for an allowlist that should be passed to the child process.

GLib implements this in its GSubprocess API. Linux supports this with close_range() and many other OSs have a closefrom() syscall. Linux also has a fallback by iterating over /proc/self/fd using the async-signal-safe getdents syscall.

DemiMarie avatar Sep 20 '25 18:09 DemiMarie

On Darwin this is done with the POSIX_SPAWN_CLOEXEC_DEFAULT flag.

comex avatar Sep 25 '25 07:09 comex

some notes on POSIX_SPAWN_CLOEXEC_DEFAULT: https://github.com/python/cpython/issues/109154 also, apparently when adding explicitly inherited file descriptors using posix_spawn_file_actions_addinherit_np they must be less than OPEN_MAX: https://github.com/joyent/libuv/issues/1483

programmerjake avatar Sep 25 '25 08:09 programmerjake

Existing programs may be relying on automatic inheritance, so this would have to be opt-in. But then we would have to make it error under circumstances where the necessary calls aren't available e.g. old linux with procfs not mounted or platforms without closerange.

related: https://github.com/rust-lang/rust/issues/145957

the8472 avatar Sep 25 '25 16:09 the8472