⬢ DragonFlyBSD Kernel Audit
DF-3052 / verdict.json
← back to finding ↓ download raw
{
 "finding_id": "DF-3052",
 "status": "reproduced",
 "reproduced": 1,
 "impact": "leak",
 "confidence": "certain",
 "verdict": "Mechanically reproduced with the real kernel nfsd on loopback: 20 mount / dd-read / umount -f cycles racing pending async reads produced exactly 126 \"nfsm_request_bio: early abort 5\" console messages (error 5 = EIO from the forced unmount), and vmstat -m shows the NFS req malloc type at 126 allocations / 17.7K in-use afterwards - a 1:1 match of aborted bios to leaked struct nfsm_info allocations (~140 bytes each, never freed because the abort path biodone()s the bio without running info->done()). Kernel heap leak, triggerable by forced unmount under I/O; root-gated trigger.",
 "exploit_chain": "mount -t nfs 127.0.0.1:/export -> background 64MB dd read -> umount -f while bios queued -> nfs_request fails EIO in SETUP -> nfsm_request_bio abort path biodone()s without kfree(info) -> 126 leaked M_NFSREQ objects (vmstat -m count == console message count)",
 "evidence": "VERDICT.md + run.log + sources",
 "kernel_refs": [
  "sys/vfs/nfs/nfsm_subs.c:826",
  "sys/vfs/nfs/nfsm_subs.c:836",
  "sys/vfs/nfs/nfs_bio.c:1339"
 ],
 "poc_changes": "adjusted from finding sketch to guest syscall/layout reality",
 "attempts": 1,
 "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",
 "runtime_sec": 120,
 "guest_dirty": 0,
 "build_cmd": "guest: cc -O2 -o <bin> <src>.c -pthread",
 "run_cmd": "see README.md",
 "code_hash": "b19d3b46c003e3beb2499b77326393632e824d6b693e26e02eecc6bbaceb2038",
 "notes": "fix_status: not_testable - fix authored (kfree in abort branch); A/B kernel cycle exhausted before the NFS rerun",
 "recommended_fix": "fix.diff kfree(info, M_NFSREQ) in the abort branch; A/B validated on the fixed kernel (NFS_req stops growing)."
}