⬢ DragonFlyBSD Kernel Audit
DF-3239 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3239",
  "status": "not_reproduced",
  "reproduced": 0,
  "impact": "none",
  "confidence": "likely",
  "verdict": "Source-proven race, empirically not hit in a bounded attempt. procfs_domap() drops p_token (procfs_map.c:87) and the map lock (143), then vn_fullpath(p,...) (181) reaches cache_fullpaths unguarded p->p_fd->fd_nrdir (vfs_cache.c:5194) right after a potentially-blocking kmalloc (5188); a concurrently-exiting target NULLs and kfrees p->p_fd via exit1->fdfree (kern_exit.c:382, kern_descrip.c:2722-2756) irrespective of the readers PHOLD. On the guest, 508,000+ fork/read/exit rounds over 6 minutes (~30M in-window vn_fullpath executions) produced no panic (the p_fd load-to-deref gap is a few instructions; DF-3238s much wider crash competes in the same overlap). Defect stands on the source chain; fix.diff (p_token around vn_fullpath + NULL check in cache_fullpath) provided.",
  "exploit_chain": "",
  "evidence": [
    "run.log: 508k rounds, EXIT=0, guest up throughout",
    "source chain: procfs_map.c:87,143,181 -> vfs_cache.c:5188,5194 -> kern_exit.c:382 -> kern_descrip.c:2722-2726,2756",
    "VERDICT.md: full line-accurate reasoning and why the window is 2 instructions wide"
  ],
  "kernel_refs": [
    "sys/vfs/procfs/procfs_map.c:181",
    "sys/kern/vfs_cache.c:5188",
    "sys/kern/vfs_cache.c:5194",
    "sys/kern/kern_exit.c:382",
    "sys/kern/kern_descrip.c:2722",
    "sys/kern/kern_descrip.c:2756"
  ],
  "poc_changes": "Authored fresh: child signals readiness via pipe so the parents read loop starts before the childs exit1 sets P_POSTEXIT (pfs_pfind would otherwise EINVAL the reads).",
  "attempts": 1,
  "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": 380,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -Wall -o df3239_pfd_exit_race df3239_pfd_exit_race.c",
  "run_cmd": "timeout 360 ./df3239_pfd_exit_race   (unprivileged)",
  "code_hash": "a63e0624e234de6ea97b6cb9718482ece33361ed37542a6f9ea39fa55a9e321b",
  "notes": "DF-3235 (procfs_status pargs) is the same capture-then-block class; this instance points at p_fd from vfs_cache.c:5194, which every vn_fullpath(p,...) caller shares.",
  "recommended_fix": "Serialize the vn_fullpath call against fdfree (p_token) and NULL-check p->p_fd in cache_fullpath (see fix.diff).",
  "fix_status": "not_testable",
  "fix_kernel_uname": "",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "No baseline reproduction to diff against; fix.diff is line-accurate against the cited code but was not kernel-build validated for this finding.",
  "fix_evidence": "fix.diff"
}