⬢ DragonFlyBSD Kernel Audit
DF-5536 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5536",
  "status": "reproduced",
  "reproduced": true,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "The dump walk uses kernel page-table frames without validation: dump_add_page(pdp[i]&PG_FRAME) at :260 and dump_add_page(pd[j]&PG_FRAME) at :281 are not is_dumpable-guarded (unlike the leaf paths at :271/:291), dump_add_page/dump_drop_page (:452/:463) have no bitmap bounds check, and :263/:285 DMAP-read the same raw frames. Demonstrated on the live guest by planting a single fake PDP entry: frame 2^47 yields Fatal trap 12: page fault while in kernel mode, fault virtual address = 0xfffff80140000000 (= vm_page_dump[frame>>18]), supervisor write data -> nested panic, wedged guest, no dump; frame 2^46 silently bit-ORs a live kernel object 2GB past the bitmap and crashes later with vm_object_hold_shared(NULL). Precondition is kernel page-table corruption (post-exploitation or the original crashing bug), so no privilege boundary is crossed - severity Low - but the dump writer turns corrupted PTEs into an uncontrolled kernel write / loss of the crash dump exactly when forensics matter.",
  "exploit_chain": "requires prior kernel memory corruption (attacker already ring-0): plant PDP/PD entry with chosen frame -> panic -> dump walk calls dump_add_page(frame) -> atomic_set_long at vm_page_dump + frame/32KB (chosen offset, bit-OR, 8-byte aligned) -> silent kernel-memory corruption or page fault; demonstrated both outcomes",
  "evidence": "panic.txt: Fatal trap 12, fault VA 0xfffff80140000000 matching the rig-predicted &vm_page_dump[0x20000000], supervisor write data, page not present, panic: page fault, no dump. panic.2-silent-corruption.txt: frame 2^46 -> nested panic: assertion obj != NULL failed in vm_object_hold_shared. run.patched.log: patched kernel, identical plant -> Dump complete.",
  "kernel_refs": [
    "sys/platform/pc64/x86_64/minidump_machdep.c:260",
    "sys/platform/pc64/x86_64/minidump_machdep.c:263",
    "sys/platform/pc64/x86_64/minidump_machdep.c:281",
    "sys/platform/pc64/x86_64/minidump_machdep.c:285",
    "sys/platform/pc64/x86_64/minidump_machdep.c:452",
    "sys/platform/pc64/x86_64/minidump_machdep.c:463",
    "sys/vm/vm_page.c:399"
  ],
  "poc_changes": "PoC authored fresh: KLD rig plants pdp[64]=frame|V in an unused kernel PDP slot (chosen far beyond kernel_vm_end after a first attempt in the first-free slot was disturbed by panic-time allocations) and panics via sysctl trigger.",
  "attempts": 4,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64 (baseline); #1: Wed Oct 7 03:43:23 UTC 2026 (patched)",
  "runtime_sec": 2700,
  "guest_dirty": 1,
  "build_cmd": "cd /root/mddiag && make obj >/dev/null 2>&1 && make && cp /usr/obj/root/mddiag/mddiag.ko .",
  "run_cmd": "kldload /root/mddiag/mddiag.ko; sysctl debug.debugger_on_panic=0; sysctl debug.mddiag=booby",
  "code_hash": "4417cc4784717abb94cb42c21f08e0c8d61111a275440c77f698b42af4a4982e",
  "notes": "Both fault variants reproduced from fresh boots; the fault VA matched the predicted bitmap OOB target byte-for-byte and the fault was a supervisor WRITE (the atomic_set_long), proving direct attribution to minidump_machdep.c:260->:459. Fixed kernel validated with the identical rig.",
  "recommended_fix": "is_dumpable() guards on the PD/PT frames at :260/:281 (before any use, incl. the DMAP reads) plus a bitmap bounds check in dump_add_page/dump_drop_page (also fixes int idx truncation for pa >= 2^49).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 1,
  "fix_verdict": "Applied fix.diff in the guest /usr/src, rebuilt and rebooted into the patched kernel; the identical booby run now skips the planted entry (is_dumpable(frame)==0) and completes the dump normally instead of Fatal-trap-12ing - bad behavior gone.",
  "fix_evidence": "run.patched.log: Dumping 668 MB ... Dump complete on the patched kernel with pdp[64]=0x800000000000|V planted (baseline: Fatal trap 12 + nested panic + no dump)"
}