⬢ DragonFlyBSD Kernel Audit
DF-5579 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5579",
  "status": "reproduced",
  "verdict": "Reproduced on the guest vkernel rig: a single 8-byte pread(2) on /dev/kmem at 0xE400000000 (inside the vkernels fixed 512GB KVA window [0x8000000000,0x10000000000) but beyond the pmap_growkernel() frontier) aborts the entire vkernel from inside the kvm_access_check() residency validator: pmap_kextract() (pmap.c:732) derefs vtopde() whose assert(x != NULL) (pmap.c:357) fires because pmap_pde() (pmap.c:273-280) returns NULL for the ungrown 1GB PDPT entry; libc assert -> SIGABRT (unhandled, exception.c:226-250) -> vkernel process DEAD with all its guests. Controls prove /dev/kmem works normally in the same boot (image-shortcut text read returns real kernel prologue bytes; grown-KVA read returns clean EFAULT). Root-in-vkernel required (kern_memio.c:841, 0640 root:kmem) -> Low severity, availability-only, pc64 DF-5358 twin. fix.diff (gate the page loop on kernel_vm_end, vm/vm_kern.h:107) validated by rebuild: trigger now returns EFAULT and the vkernel stays ALIVE to VKDONE with byte-identical positive control.",
  "reproduced": true,
  "impact": "panic",
  "confidence": "certain",
  "exploit_chain": "root inside vkernel -> open /dev/kmem -> pread at KvaStart+400GB (any address beyond kernel_vm_end within the 512GB MAP_FIXED KVA window) -> memrw -> kvm_access_check (vm_machdep.c:322-325) -> pmap_kextract -> vtopde assert -> SIGABRT -> whole vkernel process dies (all vcpus, all guest processes). No memory-safety primitive; no guest-user reachability; availability only.",
  "evidence": "panic.txt + run.baseline.log (assertion line + === vkernel alive? === DEAD); run.ctl.log (positive control: pread at 0x454780 returns 8 bytes 41 56 41 55 41 54 53 48 via the _start.._end shortcut; control EFAULT SURVIVED); run.fixed.log (post-fix: trigger EFAULT SURVIVED, VKDONE, ALIVE); vkfixbuild.log (fixed kernel build); VERDICT.md for the full chain",
  "kernel_refs": [
    "sys/platform/vkernel64/x86_64/vm_machdep.c:310",
    "sys/platform/vkernel64/x86_64/vm_machdep.c:322",
    "sys/platform/vkernel64/platform/pmap.c:732",
    "sys/platform/vkernel64/platform/pmap.c:357",
    "sys/platform/vkernel64/platform/pmap.c:273",
    "sys/platform/vkernel64/platform/pmap.c:1563",
    "sys/platform/vkernel64/include/vmparam.h:80",
    "sys/platform/vkernel64/platform/init.c:609",
    "sys/kern/kern_memio.c:285",
    "sys/platform/vkernel64/x86_64/exception.c:226"
  ],
  "poc_changes": "vkmem.c written fresh (no seed); rig rebuilt from scratch on a reset guest: DF-5474 SYSTEM_LD defsym workaround re-applied, VKERNEL64 kernel rebuilt, /vkroot.img regenerated (DF-5337/5538/5556 rig), vm.vkernel_enable=1 + /var/vkernel created (both required and missing on a fresh guest).",
  "attempts": 3,
  "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 (vkernel under test: DragonFly 6.5-DEVELOPMENT #0: Wed Oct 7 23:10:40 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/VKERNEL64)",
  "runtime_sec": 1080,
  "guest_dirty": 1,
  "build_cmd": "cc -static -O2 -o /root/vkmem vkmem.c && sh build_image.sh && cd /usr/src && make -j6 nativekernel KERNCONF=VKERNEL64",
  "run_cmd": "sh run.sh  (boots /usr/obj/usr/src/sys/VKERNEL64/kernel.debug -m 512m -r /vkroot.img -n 1 -e init_path=/bin/vkinit; runs /root/vkmem control then /root/vkmem trigger inside)",
  "code_hash": "c253c1b2ea109ad85805bed1a2394c9ca4d4e8fd488d612ae8a12c7b20335173",
  "notes": "3 boots total (baseline trigger-death, baseline positive-control, fixed trio). Zero-PDE-within-grown-range case reads DMAP(0) garbage inside pmap_kextract but is caught by kernacc (vm_machdep.c:326) -> benign; only the PDPT-invalid case crashes. The vkernel kernel build itself required the DF-5474 link workaround (already-filed finding). Pass-2 negative results for the rest of the file are in the audit JSON: cpu_fork FP pcb copy is behaviorally inert for the child (TDF_USINGFP not inherited -> npxdna()->npxinit() clobbers pcb_save at first FP use -> child sees INIT state, therefore NO fork-path amplification of the DF-5556 exec-boundary XMM leak); LDT branches dead (sysarch EOPNOTSUPP, pcb_ldt always NULL, user_ldt_* are panic stubs); PCB_DBREGS/reset_dbregs unreachable (fill/set_dbregs return ENOSYS); pcb_onfault never set in vkernel; cpu_prepare_lwps copyout of the NULL return frame is bounded by the guest vm_map fault (kernel-range stacks fail with EFAULT via copyio.c:363-367).",
  "recommended_fix": "In kvm_access_check(), reject eaddr > kernel_vm_end (grown page-table frontier, vm/vm_kern.h) before the pmap_kextract() page loop (fix.diff).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": true,
  "fix_patched_reproduced": false,
  "fix_verdict": "Applied fix.diff to the guest /usr/src copy, rebuilt VKERNEL64 (vkfixbuild.log, BUILD_RC=0), re-ran the exact trio (run_fixed.sh -> run.fixed.log): trigger now returns pread=-1/EFAULT with DF5579_trigger_SURVIVED, session reaches VKDONE, vkernel ALIVE; positive text control returns the identical 8 bytes and KVA control behaves identically to baseline. The previously-observed bad behavior (assertion + vkernel death) is gone.",
  "fix_evidence": "run.fixed.log (DF5579_trigger_SURVIVED / ALIVE / VKDONE) vs run.baseline.log (Assertion failed pmap.c:357 / DEAD); vkfixbuild.log (fixed kernel rebuild); fix.diff (git-apply-able)"
}