Repository navigation
Failing to use close-on-exec #4980
Description
Describe the bug
Most code paths in MsQuic don't create close-on-exec sockets. This is a problem because it means that MsQuic sockets will be inherited by subprocesses if the containing application calls fork+execve, posix_spawn or one of the CreateProcess (with inherit handles mode) system calls.
This can theoretically be a security issue, but the circumstances would be rather unlikely in practice. Imagine a privileged server application that spawns a child process of lower privilege. The child process would inherit privileged sockets. Many services like this are aware that they need to close all but intended handles in the child.
More likely, it's a reliability issue with keeping sockets open like that. QUIC is less affected by it than TCP, though.
Setting this flag needs to be done atomically with the creation of the socket, because you never know when another thread is going to spawn a child process.
Affected OS
- Windows
- Linux
- macOS
- Other (specify below)
Additional OS information
No response
MsQuic version
main
Steps taken to reproduce bug
This isn't a reproducible bug in the normal sense.
Expected behavior
This isn't a reproducible bug in the normal sense.
Actual outcome
This isn't a reproducible bug in the normal sense.
Additional details
How this can be fixed:
Linux:
Various APIs have ways of specifying that the new handle should be close-on-exec.
epoll_createeventfdopenfopen(eextendedfopenflag in glibc)accept(asaccept4)socketpair
Windows:
WinSock supports this by using WSASocketW instead of socket to create the socket. Specify the WSA_FLAG_NO_HANDLE_INHERIT flag. Note that you'll also need WSA_FLAG_OVERLAPPPED, because socket specifies that flag internally. accept's new socket inherits the inheritance flag from the listener socket.
macOS:
Unfortunately, macOS does not have a way to atomically create sockets with FD_CLOEXEC already set.
It might not be worthwhile to do this, and instead have a warning in the documentation. UNIX-based programs can close handles that shouldn't be inherited in the child of fork. Windows-based programs can either tell CreateProcess* to not have the child inherit handles, or use PROC_THREAD_ATTRIBUTE_HANDLE_LIST to explicitly specify handles to be inherited.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
Activity
anrossi commentedon Apr 8, 2025
What about a global configuration knob for a "forking server mode" that enables this behavior? It would need to be set before any sockets are created to have the intended effect, but would enable applications to be designed like this without requiring specialized behavior for
fork()orCreateProcess*callsMyriachan commentedon Apr 8, 2025
Sure, that'd work great. By the way, this should also get the "OS: Windows" tag.
anrossi commentedon Apr 8, 2025
I've added the tag. I'm not sure when we'll be able to schedule this work, but we're more than happy to review a PR, if you need the feature more urgently.
ahfoysal commentedon Jul 15, 2026
Hi Anthony Rossi (@anrossi), I’d like to work on this issue. Based on the discussion, I plan to add a global “forking server mode” configuration that must be enabled before socket creation, use atomic close-on-exec/no-inherit flags on Linux and Windows, and add relevant tests and documentation. Before I begin, is this still the preferred design, and should macOS remain a documented limitation?
guhetier commentedon Jul 15, 2026
Hi, I don't think an API change or global configuration should be exposed for this. Either we do it or not, but it is too specific for something to expose in an API.
I can't think of a scenario where it would be meaningful to fork/execv a running MsQuic instance and need to access the pre-existing sockets, so adding the flag is all that would be needed.
BLCCoreStudio commentedon Aug 28, 2026
I'd like to work on the Linux side of this. I don't see an open PR for it, so I'm going to audit the Linux file/socket creation paths and use atomic close-on-exec flags where supported. I'll keep the change focused and include tests where practical. Happy to coordinate if someone is already actively working on this.