{
  "finding_id": "DF-4760",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "free_vinum()s daemon-stop loop (vinum.c:215-219) queues one daemonrq_return per tick while VF_DAEMONOPEN is set, but nothing is guaranteed to drain the queue (opening /dev/vinum/controld starts no daemon, and the kernel daemon loop exits after the FIRST daemonrq_return), so kldunload with a root holder on the daemon device wedges for the holders chosen duration, permanently leaks one struct daemonq kmalloc per pass, and blocks kldload/kldstat system-wide via the kernel linker lock. Reproduced on the stock-kernel guest across 4 runs; the 300 s hold wedged kldunload exactly 300 s (serial console) and leaked +14,600 nodes (~350 KB) that remain leaked after unload; kldstat and vmstat -m hung during the wedge. Root-triggerable (controld is 0600 root), hence DoS severity, not privesc.",
  "exploit_chain": "",
  "evidence": "findings/poc/DF-4760/df4760_run2.log: 1051 D2 vstop kldunload vinum caught mid-loop and devbuf 2.07K->3.92K; serial_5min_wedge.log: holder open 10:33:03 -> vinum: unloaded 10:38:03 (=open+300s), devbuf 5.10K->19.7K (+14,600 leaked nodes); fix_run.log: patched module returns EBUSY after a bounded ~10 s with module intact and devbuf +~10, legit-daemon unload rc=0 <1 s",
  "kernel_refs": [
    "sys/dev/raid/vinum/vinum.c:215-219",
    "sys/dev/raid/vinum/vinum.c:302-307",
    "sys/dev/raid/vinum/vinum.c:461-462",
    "sys/dev/raid/vinum/vinum.c:544-548",
    "sys/dev/raid/vinum/vinumdaemon.c:150-162",
    "sys/dev/raid/vinum/vinumdaemon.c:215-235"
  ],
  "poc_changes": "no seed; wrote hold_daemon.c (open/sleep/close holder) and four run scripts; run-1 initially showed an early loop exit caused by the leftover legit vinum daemon answering the first daemonrq_return -- fixed by using a fresh kldload with no vinum commands issued; ps visibility quirks on DF worked around with devbuf sampling + serial-console timestamps",
  "attempts": 4,
  "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": 620,
  "guest_dirty": 0,
  "build_cmd": "cc -O -o /tmp/hold_daemon /tmp/hold_daemon.c",
  "run_cmd": "kldload vinum (fresh, no vinum commands); /tmp/hold_daemon 300 & sleep 2; kldunload vinum &; vmstat -m | grep devbuf; (after holder closes) kldunload completes",
  "code_hash": "5dd5190aa9e0807cfa06796f9b92bcda32bf0381945551c969ae2668ee6bc284",
  "notes": "hz=100 (kern.clockrate). Leak rate measured ~50 nodes/s (one per ~2 ticks). A fix attempt that plainly refused unload while VF_DAEMONOPEN is set (v1) was refuted on the guest (makes legit-daemon unload impossible because the kernel daemon can only exit when asked via daemonrq_return) and was replaced by the ask-once/bounded-wait/EBUSY design (v2) which validates cleanly for both the malicious-holder and legit-daemon paths.",
  "recommended_fix": "MOD_UNLOAD: queue a single daemonrq_return, wait a bounded 5*hz, return EBUSY (nothing torn down) if the daemon device is still open; make free_vinums wait queue-once and bounded (see fix.diff)",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "vinum.ko rebuilt from /usr/src patched with fix.diff v2 (make rc=0), installed, loaded. A) malicious holder: kldunload -> Device busy rc=1 after a bounded ~10 s, module intact, devbuf +~10 allocations (baseline: 300 s wedge + 14,600 leaked nodes + system-wide kldstat blockage); after holder close, clean rc=0 unload. B) legit daemon: asked once, exits, unload rc=0 in <1 s, zero leak. Bad behavior gone on both paths.",
  "fix_evidence": "findings/poc/DF-4760/fix_run.log (scenarios A and B with baseline comparisons); fix_build2.log; fix.diff in the same pack"
}