⬢ DragonFlyBSD Kernel Audit
DF-5133 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5133",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "dmabuf_fileops (sys/dev/drm/linux_dma-buf.c:107-115) is the only fileops in the kernel that leaves .fo_shutdown NULL; kern_shutdown() (kern_descrip.c:1522), the backend of shutdown(2), has no file-type or privilege check and calls it on any fd. An unprivileged process holding a dma-buf fd (render node PRIME export on real hardware) calling shutdown(fd, SHUT_RDWR) executes an indirect call to address 0: reproduced live as uid 65534 with Fatal trap 12, IP=0x0, guest wedged in DDB. fix.diff (.fo_shutdown = badfo_shutdown) was rebuilt into drm.ko on the guest and the identical trigger then returned cleanly with the guest up: fix validated.",
  "exploit_chain": "unpriv render node -> DRM_IOCTL_PRIME_HANDLE_TO_FD -> dma_buf_fd() (drm_prime.c:669) -> dma-buf fd in table; shutdown(fd, 2) -> sys_shutdown -> kern_shutdown (kern_descrip.c:1522) -> holdfp(any fd) -> fo_shutdown == NULL -> call *0 -> fatal trap 12 (IP=0). NULL-call is panic/DoS only; userland cannot map page 0 on DragonFly.",
  "evidence": "run.log (baseline: trigger output + serial Fatal trap 12, instruction pointer 0x8:0x0, current process = panic_trigger uid 65534, db> prompt); panic.txt / serial_full.log (full serial capture); kmod live-printed fo_shutdown=0 from fp->f_ops before the call; fix_run.log (patched: fo_shutdown=0xffffffff8062e5d0, shutdown RETURNED, guest up).",
  "kernel_refs": [
    "sys/dev/drm/linux_dma-buf.c:107",
    "sys/dev/drm/linux_dma-buf.c:115",
    "sys/kern/kern_descrip.c:1522",
    "sys/kern/kern_descrip.c:1531",
    "sys/sys/file.h:76",
    "sys/dev/drm/drm_prime.c:669"
  ],
  "poc_changes": "PoC written from scratch (no seed). The guest has no GPU, so a kmod (dmabugdemo.ko) creates the dma-buf fd by calling the stock dma_buf_export()/dma_buf_fd() from drm.ko in the firing processs context; kern_shutdown() -> NULL fo_shutdown is the genuine unmodified path. Fixed one build error (SHUT_RDWR needed sys/socket.h).",
  "attempts": 2,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026     root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "runtime_sec": 900,
  "guest_dirty": 0,
  "build_cmd": "cd /root/poc && cc -O -o panic_trigger panic_trigger.c && printf KMOD=\\tdmabugdemo\\nSRCS=\\tdmabuf_demo.c\\n\\n.include <bsd.kmod.mk>\\n > Makefile && make",
  "run_cmd": "kldload drm && kldload /usr/obj/root/poc/dmabugdemo.ko && su -m nobody -c /tmp/panic_trigger",
  "code_hash": "10becddfbe5d8fd28d8b5c4189d51d2724913171b242e9a4d6b19fd3ff7b206e",
  "notes": "Every other fileops in the tree sets fo_shutdown (vnops/kqueue->nofo_shutdown, sockets->soo_shutdown, pipes->pipe_shutdown, mqueue/badfileops->badfo_shutdown); dmabuf_fileops is the sole outlier. Guest reset clean (vm.sh reset with-src) after validation.",
  "recommended_fix": "Add .fo_shutdown = badfo_shutdown to dmabuf_fileops in sys/dev/drm/linux_dma-buf.c (one line); optionally also add a DTYPE check to kern_shutdown() as defense-in-depth.",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Applied fix.diff (.fo_shutdown = badfo_shutdown) to the guests /usr/src copy, rebuilt and installed drm.ko, rebooted, re-ran the identical uid-65534 trigger: fo_shutdown now resolves (0xffffffff8062e5d0 = badfo_shutdown), shutdown() returns, guest stays up. Baseline panic reproduced on the stock module minutes earlier on the same guest.",
  "fix_evidence": "fix_build.log (patch + drm.ko rebuild + install); fix_run.log (shutdown RETURNED (fo_shutdown set => fixed), PANIC_RC=0, guest up).",
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0 (same base kernel; only /boot/kernel/drm.ko rebuilt from patched source)"
}