Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upDanger of leaking file descriptors when spawning processes #12148
Comments
alexcrichton
added
the
A-io
label
Feb 10, 2014
This comment has been minimized.
This comment has been minimized.
|
... but what if a forked process wants to hang on to existing file descriptors? |
This comment has been minimized.
This comment has been minimized.
|
#13790 has example code triggering this problem as well as some solutions for some platforms. |
thestinger
added
A-security
I-nominated
labels
Sep 19, 2014
This comment has been minimized.
This comment has been minimized.
|
Opening all file descriptors as CLOEXEC should be the default and can be fully implemented on both Linux and Windows. I don't know if this can be done with absolutely zero race conditions on OS X and FreeBSD (atomic operations rather than setting it after opening), but it's probably possible. This is a major security issue and has backwards compatibility implications. |
This comment has been minimized.
This comment has been minimized.
|
FreeBSD 10, like Linux >= 26.27, has atomic O_CLOEXEC system calls. For other POSIX platforms, I imagine you could manually clean up in a pthread_atfork() handler, though that won't work for file descriptors > RLIMIT_NOFILE. OS X has a POSIX_SPAWN_CLOEXEC_DEFAULT posix_spawnattr_t flag but that only helps when spawning a new process, not when you want to fork. You use posix_spawn_file_actions_addinherit_np() for file descriptors that the new process should inherit but that is complicated by the fact that it only accepts file descriptors < OPEN_MAX (10,240.) |
bnoordhuis
referenced this issue
Sep 19, 2014
Open
darwin: spawn new process with POSIX_SPAWN_CLOEXEC_DEFAULT #1483
This comment has been minimized.
This comment has been minimized.
|
this issue should be considered blocking the stabilization of the relevant API's. The relevant API's are not yet considered stable (they are currently So, assigning P-high, not 1.0. |
pnkfelix
added
P-medium
and removed
I-nominated
labels
Sep 25, 2014
This comment has been minimized.
This comment has been minimized.
|
Closing in favor of rust-lang/rfcs#941 |
alexcrichton
closed this
Mar 5, 2015
This comment has been minimized.
This comment has been minimized.
|
This is a real, serious security issue and needs to be fixed regardless of whether a proposed redesign happens. Closing the issue doesn't change the fact that it's getting a CVE assigned if it's not fixed by 1.0. |
This comment has been minimized.
This comment has been minimized.
|
For the record, I'm worried about closing this out without a clear resolution for 1.0. While I think the APIs for the new IO system are in good shape (and are quite conservative), I think we should take an additional pass through the implementation looking for issues like this, and try to document as much of the details as possible (i.e. what syscalls a given API maps to, and what promises we're making behavior-wise). |
alexcrichton
referenced this issue
Mar 10, 2015
Closed
File descriptors created by Rust should be automatically close-on-exec #23233
This comment has been minimized.
This comment has been minimized.
|
I worry people will rely on calling |
pcwalton
reopened this
Mar 10, 2015
pcwalton
added
the
I-nominated
label
Mar 10, 2015
This comment has been minimized.
This comment has been minimized.
|
They leak whether or not you call |
This comment has been minimized.
This comment has been minimized.
|
To explicitly list all open file descriptors, we can replace the Anyway, |
This comment has been minimized.
This comment has been minimized.
This will also help to reduce the syscall storm when using |
This comment has been minimized.
This comment has been minimized.
|
1.0, P-backcompat-libs, I-needs-decision. |
pnkfelix
added this to the 1.0 milestone
Mar 12, 2015
pnkfelix
added
P-backcompat-libs
I-needs-decision
and removed
I-nominated
labels
Mar 12, 2015
This comment has been minimized.
This comment has been minimized.
|
I believe that, where possible, the Doing a bunch of calls to close(2) would be a severe performance penalty on every fork()/exec() for systems that lack procfs. It also would not prevent the FD leak for processes created outside of Rust. This does mean bypassing C's stdio. |
This comment has been minimized.
This comment has been minimized.
It's always possible to avoid leaks without the loop hack, at least on Linux and Windows. It's not an unsolved problem. |
This comment has been minimized.
This comment has been minimized.
|
I know that it is always possible. I am just saying that Rust should still set the This is especially important when a Rust library exposes a C API, as the C program may not be aware of the FD creation in Rust code. I hope that I am not belaboring an already-made point -- please let me know if I am. I guess I am emphatically agreeing with I0kod. |
This comment has been minimized.
This comment has been minimized.
|
I'm stating that it's always possible to set |
This comment has been minimized.
This comment has been minimized.
|
On Mon, 2015-03-16 at 22:03 -0700, Daniel Micay wrote:
|
alexcrichton
self-assigned this
Apr 2, 2015
This comment has been minimized.
This comment has been minimized.
|
nominating for future triage next week. |
pnkfelix
added
the
I-nominated
label
Apr 2, 2015
This comment has been minimized.
This comment has been minimized.
|
Note: @alexcrichton and I discussed this at length today, and believe that the way forward is to indeed set CLOEXEC, to do so atomically whenever possible (not possible on all platform versions in all scenarios), and to forgo the close loop when spawning processes. We can clearly document the behavior of |
This comment has been minimized.
This comment has been minimized.
|
We should move using CLOEXEC before 1.0, so suggesting that nomination leave the labels/milestone as-is. |
alexcrichton commentedFeb 10, 2014
We're not opening anything with
CLOEXEC, so we're in theory leaking file descriptors across forks (they stay alive as long as the child stays alive).We currently use
getdtablesizeto close all these descriptors, but as #12103 (comment) says, this isn't enough if a thread manually lowersRLIMIT_NOFILE.We should consider opening file descriptors wherever possible with
CLOEXEC, but this also sounds like it's a tricky situation (not always supported to specify the flag at open-time).