Skip to content

Instantly share code, notes, and snippets.

@antonfirsov
Last active January 24, 2020 18:44
Show Gist options
  • Save antonfirsov/1e880daee8b0582880b635fe716c27af to your computer and use it in GitHub Desktop.
Save antonfirsov/1e880daee8b0582880b635fe716c27af to your computer and use it in GitHub Desktop.
WSADuplicateSocket vs Handle inheritance
void PrintInheritable(SOCKET s, const char* name) {
DWORD info;
if (GetHandleInformation((HANDLE)s, &info))
{
bool inheritable = (info & HANDLE_FLAG_INHERIT) == HANDLE_FLAG_INHERIT;
std::cout << name << " inheritable: " << inheritable << std::endl;
}
}
int main()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) return 1;
// Make sure original socket is not inheritable:
DWORD e_x_p_e_c_t_e_d = WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT;
SOCKET original = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, NULL, e_x_p_e_c_t_e_d);
if (original == INVALID_SOCKET) return 1;
PrintInheritable(original, "Original");
WSAPROTOCOL_INFOW protocolInfo = {};
DWORD processId = GetCurrentProcessId();
if (WSADuplicateSocket(original, processId, &protocolInfo) != 0) return 1;
closesocket(original);
// Try to enforce the same behavior on clone handle:
SOCKET clone = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &protocolInfo, 0, e_x_p_e_c_t_e_d);
if (clone == INVALID_SOCKET) return 1;
PrintInheritable(clone, "Clone");
closesocket(clone);
WSACleanup();
return 0;
}
Original inheritable: 0
Clone inheritable: 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment