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 author's 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 E1's 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"
}