DF-3184 / verdict.json
{ "finding_id": "DF-3184", "status": "not_reproduced", "reproduced": 0, "impact": "none", "confidence": "likely", "verdict": "Source-certain use-after-free write (CWE-416): procfs_exits at_exit walk vhold()s a vnode (which explicitly does not prevent reclaim), blocks in void vx_get() which cannot fail or revalidate, then writes pfs->pfs_pid |= PFS_DEAD through a pfsnode that a concurrent vgone_vxlocked (vnlru under vnode pressure, or umount -f vflush) may already have kfree()d via procfs_freevp. Every chain stage was individually proven on an instrumented guest kernel (nodes created and marked=12 by unpriv exits; forced vflush reclaiming them; precise dounmount retry-loop timing), but the final microsecond-scale scan->vx_get vs vgone coincidence never manifested across ~10,000 flush-aimed exit-walks in 17 configurations: dounmounts retry loop always drains the last walking exit before flushing (adversarial bimodal feedback) and fork-storm load jitters exit1s walk past the 5-10ms flush window. Primitive if triggered: one fixed 4-byte OR (0x80000000) at offset 20 of a freed chunk in the dedicated M_PROCFS zone -> live-pfsnode corruption (procfs DoS) or INVARIANTS panic via vx_put/vnode_terminate KKASSERT(v_state==VS_ACTIVE); not a plausible uid=0 primitive (fixed value/offset, type-constrained zone).", "exploit_chain": "", "evidence": [ "findings/poc/DF-3184/VERDICT.md (full chain trace + per-run analysis)", "findings/poc/DF-3184/run.13.log (3124 marked>0 walks; poisoned-mode unmount 13.0s +/- 0.02s)", "findings/poc/DF-3184/run.14.log (dual-batch: 1404 marked>0 walks, 0 stale after msgbuf fix)", "findings/poc/DF-3184/run.17.log (light mode 2064 walks, bimodal flip to 13s exhaustion)", "findings/poc/DF-3184/env.txt (guest uname, sysctls, source hashes)", "kernel instrumentation: stale-pfs detector printed only when VTOPFS(vp)!=pfs after vx_get; never fired" ], "kernel_refs": [ "sys/vfs/procfs/procfs_subr.c:531-549", "sys/vfs/procfs/procfs_subr.c:546", "sys/vfs/procfs/procfs_subr.c:249-273", "sys/vfs/procfs/procfs_subr.c:115-130", "sys/kern/vfs_lock.c:431-445", "sys/kern/vfs_lock.c:728-735", "sys/kern/vfs_lock.c:971-1009", "sys/kern/vfs_mount.c:1165-1181", "sys/kern/vfs_subr.c:1551-1604", "sys/kern/kern_exit.c:348-362" ], "poc_changes": "Seed sketch fully rewritten: unsynchronized exit-storm racer (df3184_race.c) upgraded to marker-synchronized scratch-mount cycler (df3184_sync.c + df3184_mountd.c) after measuring the inactive-queue FIFO delay (~300s under 70k-vnode pressure) and dounmounts bimodal retry behavior (1ms / 256ms / 12.55s); added tchain.c chain prover and an in-guest instrumented kernel proving each stage.", "attempts": 17, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #3: Tue Sep 8 01:30:31 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64 (stock baseline: #0 Thu Jul 2 06:02:54 UTC 2026)", "runtime_sec": 21600, "guest_dirty": 0, "build_cmd": "cc -O2 -Wall -o df3184_sync df3184_sync.c && cc -O2 -Wall -o df3184_mountd df3184_mountd.c", "run_cmd": "./df3184_mountd /procN 300 1200 & ; su -m nobody -c ./df3184_sync sync /procN 0 0.252 48 600 /tmp/df3184/cycle.a /tmp/df3184/cycle.b", "code_hash": "7d419969e566618056bed2d63455b90b014dfe428a7042a7f5590f60eef58b87", "notes": "Race is real per source; not caught at available budget. auxrecovervnodes2 never moved (the cleanfreevnode mid-reclaim auxref abort is the near-miss signature and also never fired). Recommend filing upstream with the one-line v_data revalidation fix regardless; the same stale-pointer pattern should be audited in any other consumer of vhold+vx_get on cached fs nodes.", "recommended_fix": "After vx_get(vp) in procfs_exit, only write when vp->v_data still equals the cached pfs: if (VTOPFS(vp) == pfs) pfs->pfs_pid |= PFS_DEAD;", "fix_status": "not_testable", "fix_kernel_uname": "", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "No reproduced baseline exists to validate the fix against; the fix condition is identical to the instrumentation detector that never fired, so patched behavior is indistinguishable on this guest.", "fix_evidence": "findings/poc/DF-3184/fix.diff" } |