Created
November 14, 2019 00:20
-
-
Save Myriachan/2ee3b11e7e0de4007a574a53f506c2f8 to your computer and use it in GitHub Desktop.
AFUnixIoctlIssue.cpp - demo of SIO_AF_UNIX_GETPEERPID bug
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #define _WIN32_WINNT 0x0A00 | |
| #include <WinSock2.h> | |
| #include <Windows.h> | |
| #include <afunix.h> | |
| #include <cstdio> | |
| #include <cstddef> | |
| #include <cstring> | |
| #include <cwchar> | |
| #pragma comment(lib, "ws2_32.lib") | |
| int wmain() | |
| { | |
| WSADATA wsadata; | |
| int wsaerror = WSAStartup(MAKEWORD(2, 2), &wsadata); | |
| if (wsaerror != 0) | |
| { | |
| std::wprintf(L"WSAStartup failed: %d\n", wsaerror); | |
| return 1; | |
| } | |
| DeleteFileA("AFUnixIoctlIssue.pipe"); | |
| struct sockaddr_un address; | |
| std::memset(&address, 0, sizeof(address)); | |
| address.sun_family = AF_UNIX; | |
| strcpy_s(address.sun_path, "AFUnixIoctlIssue.pipe"); | |
| int addressSize = static_cast<int>(offsetof(struct sockaddr_un, sun_path) + std::strlen(address.sun_path) + 1); | |
| SOCKET listener = socket(AF_UNIX, SOCK_STREAM, 0); | |
| if (listener == INVALID_SOCKET) | |
| { | |
| std::wprintf(L"socket 1 failed: %d\n", WSAGetLastError()); | |
| return 1; | |
| } | |
| if (bind(listener, reinterpret_cast<struct sockaddr *>(&address), addressSize) != 0) | |
| { | |
| std::wprintf(L"bind failed: %d\n", WSAGetLastError()); | |
| return 1; | |
| } | |
| if (listen(listener, 5) != 0) | |
| { | |
| std::wprintf(L"listen failed: %d\n", WSAGetLastError()); | |
| return 1; | |
| } | |
| SOCKET connector = socket(AF_UNIX, SOCK_STREAM, 0); | |
| if (connector == INVALID_SOCKET) | |
| { | |
| std::wprintf(L"socket 2 failed: %d\n", WSAGetLastError()); | |
| return 1; | |
| } | |
| // Use non-blocking so that connect will never block on accept being called. | |
| // That shouldn't happen normally, but don't rely on that behavior. | |
| u_long yes = 1; | |
| if (ioctlsocket(connector, FIONBIO, &yes) != 0) | |
| { | |
| std::wprintf(L"ioctlsocket failed: %d\n", WSAGetLastError()); | |
| return 1; | |
| } | |
| if (connect(connector, reinterpret_cast<struct sockaddr *>(&address), addressSize) != 0) | |
| { | |
| if (WSAGetLastError() != WSAEWOULDBLOCK) | |
| { | |
| std::wprintf(L"connect failed: %d\n", WSAGetLastError()); | |
| return 1; | |
| } | |
| } | |
| struct sockaddr_un acceptedAddress; | |
| int acceptedAddressSize = sizeof(acceptedAddress); | |
| SOCKET accepted = accept(listener, reinterpret_cast<struct sockaddr *>(&acceptedAddress), &acceptedAddressSize); | |
| if (accepted == INVALID_SOCKET) | |
| { | |
| std::wprintf(L"accept failed: %d\n", WSAGetLastError()); | |
| return 1; | |
| } | |
| std::wprintf(L"socket established\n"); | |
| // Don't bother waiting; if it fails, whatever. | |
| send(connector, "kitty", 5, 0); | |
| std::wprintf(L"pid: %lu\n", GetCurrentProcessId()); | |
| u_long kitty; | |
| DWORD kittySize = 0xCCCCCCCC; | |
| int kittyResult = WSAIoctl(accepted, FIONREAD, nullptr, 0, &kitty, sizeof(kitty), &kittySize, nullptr, nullptr); | |
| std::wprintf(L"kitty: %d %lu %lu\n", kittyResult, kitty, kittySize); | |
| u_long meow; | |
| DWORD meowSize = 0xCCCCCCCC; | |
| int meowResult = WSAIoctl(accepted, SIO_AF_UNIX_GETPEERPID, nullptr, 0, &meow, sizeof(meow), &meowSize, nullptr, nullptr); | |
| std::wprintf(L"meow: %d %lu %lu\n", meowResult, meow, meowSize); | |
| return 0; | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See microsoft/WSL#4676