Skip to content

Instantly share code, notes, and snippets.

@Myriachan
Created November 14, 2019 00:20
Show Gist options
  • Select an option

  • Save Myriachan/2ee3b11e7e0de4007a574a53f506c2f8 to your computer and use it in GitHub Desktop.

Select an option

Save Myriachan/2ee3b11e7e0de4007a574a53f506c2f8 to your computer and use it in GitHub Desktop.
AFUnixIoctlIssue.cpp - demo of SIO_AF_UNIX_GETPEERPID bug
#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;
}
@Myriachan
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment