Windows handles can be set to be either inheritable or not, to control whether child processes will receive them (when bInheritHandles
in CreateProcess
is TRUE). However, using SetHandleInformation
to mark a SOCKET non-inheritable does not always work. In particular, when certain Layered Service Providers (LSPs) are installed, the child process inherits the handle anyway. This is particularly likely to cause bugs with listening sockets. (But, because of another issue, if the child were to try using the socket, it would not be able! A real catch-22!)
SetHandleInformation
.bInheritHandles
true.When a (non-IFS) LSP is installed, eg. PCTools Internet Security, the listening socket will be open in the child (visible in netstat
), despite SetHandleInformation
being called on the socket to disable inheritance before creating the child.
For an alternative scenario, see the (brief) steps in KB2398202.
It is not possible in general to set SOCKET handles non-inheritable. That is, when certain (non-IFS) LSPs are installed, even if you mark handles in your process specifically non-inheritable, it is not possible to stop a child process with bInheritHandles=TRUE
from receiving them.
LSPs are commonly used by firewall or A/V products to filter all TCP connections. The LSP is a DLL loaded into your process by WinSock which handles all the TCP operations, typically by performing some filtering and then passing the call straight down to the underlying WinSock implementation. The LSP works by creating a dummy handle for each actual SOCKET handle produced the WinSock implementation: your call to WSASocket will give you the dummy handle; when you use the dummy handle, the call is sent to the LSP which created it; the LSP then maps the dummy back to the actual handle, and passes on the operation (such as accept
or bind
) to the underlying handle.
The problem is therefore that calling SetHandleInformation
on the sockets you create is not enough: the underlying handle that you never see (used internally by the LSP) is still inherited by child processes.
CreateProcess
allowing any inheritance from an application which uses sockets. This is the most reliable solution. Instead, to set up a communication with the child, create a named pipe with suitable permissions, pass its name on the commandline to the child, and connect back in the child. Then manually pass over any handles you wish the child to inherit. This is secure, since although the commandline may be readable by other users, only the actual user token of the child can connect to the pipe if it's set up correctly.WSA_FLAG_NO_HANDLE_INHERIT
flag was added to WSASocket
. (This is as much documentation of the problem as I can find from Microsoft. Creating the hotfix is pretty much acknowledgement that it's not possible without it to prevent the Base Service Provider handles from being inherited. It's not well advertised though!)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With