{
  "finding_id": "DF-2676",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "vm_page_grab() dereferences m->valid at sys/vm/vm_page.c:3882 after setting m=NULL on the 'page exists but busy' error path when the caller did not pass VM_ALLOC_RETRY (vm_page.c:3841-3843); the alloc-failure path correctly does 'goto failed' (:3859) but this path forgot. Proven deterministically with a two-kernel-thread KLD: Fatal trap 12 at fault VA 0x76 (offsetof(struct vm_page, valid)), faulting instruction 'movzbl 0x76,%eax' inside vm_page_grab, on the stock INVARIANTS guest kernel. Unprivileged in-tree reachability is currently latent: the only non-RETRY caller (sysv_shm prealloc loop, sysv_shm.c:582) holds the object token exclusively for its whole loop, the loop cannot block mid-iteration, and phys_pager_getpage marks prealloc'd pages PG_UNQUEUED, which excludes the only token-free page busier (the vm_page_hash_get quick-fault soft-busy); two dedicated userland racers (thousands of shmget-prealloc vs shmat+fault races, shm_use_phys=2) could not reach it, matching the source analysis. Any kernel caller (future in-tree code or third-party KLD) using the documented non-RETRY contract trips the NULL deref immediately, as demonstrated. Fixed-address read at NULL - panic/DoS only, no escalation.",
  "exploit_chain": "KLD trigger (root via kldload, or any future kernel caller): thread A busies a page in an object; thread B calls vm_page_grab(obj, 0, VM_ALLOC_NORMAL) -> vm_page_lookup_busy_try(...,TRUE,...) returns error=TRUE (PBUSY_LOCKED or soft-busy) -> vm_page_sleep_busy sleeps once -> A wakes the page -> B resumes, m=NULL; break -> 'if (m->valid == 0)' reads NULL+0x76 -> Fatal trap 12 -> kernel panic. No user-controllable pointer; read-only primitive.",
  "evidence": [
    "panic.txt: Fatal trap 12, fault virtual address 0x76, 'Stopped at vm_page_grab.cold.30: movzbl 0x76,%eax' with the grabber/holder marker lines",
    "df2676.c: deterministic KLD trigger (two kthreads)",
    "run_fixed.log: same trigger on patched kernel -> 'DF-2676: grabber: grab returned 0 (no panic?!)', guest survived",
    "VERDICT.md: full reachability analysis why the sysv_shm prealloc caller cannot observe a busy page today"
  ],
  "kernel_refs": [
    "sys/vm/vm_page.c:3838",
    "sys/vm/vm_page.c:3841",
    "sys/vm/vm_page.c:3843",
    "sys/vm/vm_page.c:3882",
    "sys/vm/vm_page.c:3859",
    "sys/kern/sysv_shm.c:582"
  ],
  "poc_changes": "Finding sketch proposed racing sysv_shm prealloc vs shmat faults; source analysis proved that caller cannot reach the error path (object held exclusively, non-blocking loop, PG_UNQUEUED pages), so the PoC was rewritten as a deterministic in-kernel KLD trigger. Two userland racers kept in the pack as the negative-result evidence. KLD iteration 1 did vm_object_hold in MOD_LOAD (syscall context) causing an unrelated token-accounting panic; fixed by moving all object work into a kernel thread. kthread_create signature fixed to (func,arg,tdp,fmt,...).",
  "attempts": 5,
  "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": 2820,
  "guest_dirty": 0,
  "build_cmd": "cd /root/df2676_mod && printf 'KMOD= df2676\\nSRCS= df2676.c\\nSYSDIR= /usr/src/sys\\n.include \"${SYSDIR}/conf/kmod.mk\"\\n' > Makefile && make",
  "run_cmd": "kldload /root/df2676_mod/df2676.ko",
  "code_hash": "a5bd0d8b1676e6a587901895de07423485c820eb419121c83d3dadb46f515689",
  "notes": "Latent for unprivileged attackers on stock kernel (parallels DF-0942 class, but with a real in-tree caller and a documented non-RETRY API contract). Fixed-address NULL read: no exploitation beyond panic even when reached. Recommended fix also improves the doc-comment contract.",
  "recommended_fix": "vm_page_grab(): on the busy-error path without VM_ALLOC_RETRY, 'goto failed' instead of 'break' so the NULL is returned without dereferencing m->valid.",
  "fix_status": "fixed",
  "fix_kernel_uname": "DragonFly 6.5-DEVELOPMENT #1: Sun Aug 30 13:38:49 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Patched kernel (fix.diff: break->goto failed; built via make -j6 nativekernel KERNCONF=X86_64_GENERIC + installkernel, uname #1 13:38:49) runs the identical KLD trigger to completion: vm_page_grab returns NULL cleanly ('grab returned 0'), no trap, guest stays up. Baseline stock kernel panics at the same trigger.",
  "fix_evidence": [
    "run_fixed.log (patched-kernel dmesg/console capture)",
    "fix.diff"
  ]
}
