DF-4377 / chk_bktr.c
/* * DF-4377 reachability probe — bktr_card.c uninitialized-EEPROM disclosure. * * The vulnerable path is device-side (probeCard() at attach / at first open * after a hw.bt848.card sysctl change). There is no direct userland trigger * for the *uninitialized* read itself: the userland-reachable BT848_REEPROM * ioctl (bktr_core.c:2086) drives the same readEEProm() helper but always * into a zeroed kernel buffer (mapped_ioctl bzero's IOC_OUT buffers), so the * CWE-457 exposure is only via the boot/probe kprintf()s at bktr_card.c:676, * :757 and :814. * * This probe documents attacker reachability of the driver surface from an * unprivileged account (device nodes are mode 0444, ioctls allowed on * O_RDONLY opens) and reports whether a bktr(4) device is present to observe * the console/dmesg output of a failed probe. * * Expected on real hardware: probe messages appear in dmesg; a card whose * EEPROM ACKs the probe but NAKs the sequential read makes probeCard print * uninitialized stack bytes ("subsystem 0x%04x 0x%04x" from eeprom[252..255] * that readEEProm() never filled). * * Expected on the audit QEMU guest: /dev/bktr0 does not exist -> exit 2. */ #include <sys/ioctl.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> /* mirror of sys/dev/video/bktr/ioctl_bt848.h */ struct eeProm { short offset; short count; unsigned char bytes[256]; }; #define BT848_REEPROM _IOWR('x', 51, struct eeProm) int main(void) { struct eeProm ee; int fd; fd = open("/dev/bktr0", O_RDONLY); /* 0444 node: unpriv open */ if (fd < 0) { printf("DF-4377: /dev/bktr0 not present: %s\n", strerror(errno)); printf("DF-4377: guest has no bktr(4) hardware; the " "probe-time uninit path cannot be exercised.\n"); return (2); } printf("DF-4377: /dev/bktr0 opened unprivileged; issuing benign " "BT848_REEPROM(0,4)\n"); memset(&ee, 0, sizeof(ee)); ee.offset = 0; ee.count = 4; if (ioctl(fd, BT848_REEPROM, &ee) < 0) printf("DF-4377: BT848_REEPROM: %s (expected benign path)\n", strerror(errno)); else printf("DF-4377: read %d bytes: %02x %02x\n", ee.count, ee.bytes[0], ee.bytes[1]); printf("DF-4377: for the uninit disclosure, watch dmesg during " "attach/open probe of a card whose EEPROM probe-ACKs but " "read-NAKs (bktr_card.c:667/676/757/794/814)\n"); close(fd); return (0); } |