⬢ DragonFlyBSD Kernel Audit
DF-3012 / verdict.json
← back to finding ↓ download raw
{
 "finding_id": "DF-3012",
 "status": "not_reproduced",
 "reproduced": 0,
 "impact": "none",
 "confidence": "likely",
 "verdict": "Defect is code-certain: hammer_ip_add_bulk() (hammer_object.c:974-977) and hammer_ip_add_direntry() (:711-716) release a never-inserted memory record without HAMMER_RECF_DELETED_FE, and hammer_rel_mem_record() (:374-393) only destroys flagged records -- so any hammer_blockmap_reserve() failure at buffer-flush time (hammer_vnops.c:3251) permanently leaks one ~224B record (plus entry data in the direntry case) in the HAMMER-others zone; the authors own sibling path (hammer_io.c:1793-1795) sets the flag, proving the omission. Phase V could not organically produce a reservation failure on the lab guest in six experiment classes (plain fill, 40k tiny-file spray, mmap/msync -- which is gated too because vnode_pager_putpages calls VOP_WRITE, 6-writer unique-data races on fast and slow backing stores, and a run with the checkspace headroom removed via vfs.hammer.limit_dirtybufspace=2M): the checkspace gate plus the effectively synchronous strategy pipeline keeps the blockmap from ever running dry behind the gate on this hardware. Residual real triggers (freemap bread I/O errors, concurrent reblock/prune/mirror, drain-lag topologies where in-flight dirty exceeds the 49MB per-mount reserve which is half the ~103MB global dirty cap, reduced limit_dirtybufspace) keep the finding Medium/likely; guest stayed healthy, no panic, no leak observed, hence not_reproduced.",
 "exploit_chain": "",
 "evidence": [
  "findings/poc/DF-3012/VERDICT.md (full narrative incl. per-experiment results)",
  "findings/poc/DF-3012/EXPERIMENTS.md (E1-E6 chronological log)",
  "findings/poc/DF-3012/run.log (decisive E6 run: sysctl headroom removed, 0 reservation failed, zone 10->184 allocs churn only, persistence stage flat)",
  "findings/poc/DF-3012/env.txt (guest uname, INVARIANTS kernel, zone snapshot, sysctl state)",
  "sys/vfs/hammer/hammer_object.c:974-977 vs sys/vfs/hammer/hammer_io.c:1793-1795"
 ],
 "kernel_refs": [
  "sys/vfs/hammer/hammer_object.c:974",
  "sys/vfs/hammer/hammer_object.c:711",
  "sys/vfs/hammer/hammer_object.c:363",
  "sys/vfs/hammer/hammer_vnops.c:3251",
  "sys/vfs/hammer/hammer_blockmap.c:419",
  "sys/vfs/hammer/hammer_blockmap.c:1267",
  "sys/vfs/hammer/hammer_io.c:1793"
 ],
 "poc_changes": "Four PoC generations: (1) write-fill+mmap/msync loops (mmap proved gated via VOP_WRITE), (2) tiny-file spray op3012.c 20k/40k files, (3) 6-parallel unique-data writers with prebuilt random source on fast/slow images (dedup defeated after discovering E1s low-entropy pages deduped), (4) deterministic attempt with vfs.hammer.limit_dirtybufspace=2M. writers.sh quoting for su -m nobody fixed via executable script.",
 "attempts": 6,
 "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": 4200,
 "guest_dirty": 1,
 "build_cmd": "cc -O -o /tmp/op3012 /tmp/op3012.c -Wall",
 "run_cmd": "sh /tmp/run3012.sh (root harness; attacker processes as nobody)",
 "code_hash": "4292d0978cdce728764afa45da87f3be13c707d905b546eef725c66730ff2605",
 "notes": "Not a memory-corruption primitive: permanent kernel heap resource leak (availability) per failed direct-write reservation; no uid0 route. Side observation logged for triage (out of file scope): msync(2) returns success while vnode_pager_putpages fails the write with ENOSPC (dmesg vnode_pager_putpages: I/O error 28), i.e. the pager error is not propagated to userspace.",
 "recommended_fix": "Set HAMMER_RECF_DELETED_FE on the record before hammer_rel_mem_record() in both error paths (hammer_object.c:711-716, :974-977), matching hammer_io.c:1793 -- see findings/poc/DF-3012/fix.diff (git-apply verified).",
 "fix_status": "not_testable",
 "fix_kernel_uname": "",
 "fix_baseline_reproduced": 0,
 "fix_patched_reproduced": 0,
 "fix_verdict": "fix.diff authored against the read-only sys/ tree and git-apply --check verified; kernel build validation skipped because the leak trigger (blockmap reservation failure) could not be reproduced on the baseline guest, so there is no observable to compare against.",
 "fix_evidence": "findings/poc/DF-3012/fix.diff"
}