DragonFlyBSD Kernel Audit
DF-2666 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-2666",
  "status": "not_reproduced",
  "reproduced": 0,
  "impact": "none",
  "confidence": "likely",
  "verdict": "The missing fdrop(fp) on hammer2_ioctl_recluster()'s two error returns (VFS_ROOT failure; the focus==NULL EINVAL branch) is certain by code inspection against the one-way ref-transfer contract of hammer2_cluster_reconnect/kdmsg_iocom_reconnect, but the leak branch could not be entered on the stock guest: 200/200 RECLUSTER calls took the success path (healthy iroot cluster), kern.openfiles delta was exactly 0 (ref accounting balanced), and no userland-constructible degraded-cluster state was found that yields focus==NULL with nchains!=1. Ceiling is one permanently pinned struct file per failing call, privileged caller only (SYSCAP_NOVFS_IOCTL). Bonus: ~1250 rapid reconnect cycles stress-tested the reconnect kill/join/teardown ordering with no wedge or panic.",
  "exploit_chain": "",
  "evidence": [
    "run.log: RECLUSTER_OK=200 RECLUSTER_EINVAL=0, OPENFILES DELTA=0 across 200 calls (success-path balance, leak branch unenterable)",
    "VERDICT.md section 1: static proof of the two leak paths (hammer2_ioctl.c:214/226-231) against the ownership contract (kern_dmsg.c:130 'We own that ref now')",
    "fix.diff: adds fdrop(fp) when error != 0 after holdfp",
    "dmesg diff (610 new lines): per-cycle VOLDATA DUMP/INITIATE SPANs/CONN WAS TERMINATED proving teardown re-entry into hammer2_autodmsg with msglk released — no panic over ~1250 cycles"
  ],
  "kernel_refs": [
    "sys/vfs/hammer2/hammer2_ioctl.c:212",
    "sys/vfs/hammer2/hammer2_ioctl.c:214",
    "sys/vfs/hammer2/hammer2_ioctl.c:226-231",
    "sys/vfs/hammer2/hammer2_iocom.c:77-85",
    "sys/kern/kern_dmsg.c:128-131",
    "sys/kern/kern_dmsg.c:149-152"
  ],
  "poc_changes": "fresh PoC (no seed); sized down from 2000 to 200 iterations after measuring ~1 s per reconnect cycle (hz/2 teardown sleeps)",
  "attempts": 2,
  "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": 210,
  "guest_dirty": 0,
  "build_cmd": "cc -O -I/usr/src/sys -o df2666_trigger df2666_trigger.c",
  "run_cmd": "sh /root/poc/df2666/run_df2666.sh  (guest, root; mounts /dev/vn0@testvol on /mnt/h2poc2666, 200x HAMMER2IOC_RECLUSTER)",
  "code_hash": "28d3a0ed65f2c5a5cdc3f166a5f924d6fde32a4b9eda77ad19ce582a7525aa73",
  "notes": "Privilege-gated (root) resource leak; also noted lockless reads of cluster->focus/array[0].chain in the same function (speculative transient-NULL race, not observed in 200 runs). Fix validation not run: branch unenterable, patch changes no executable path of this run -> fix_status not_testable.",
  "recommended_fix": "In hammer2_ioctl_recluster(), fdrop(fp) whenever the function returns an error after a successful holdfp() (the reference is transferred into iocom->msg_fp only on the success branches)."
}