{
  "finding_id": "DF-4280",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "REPRODUCED: the CCDIOCCLR busy-guard `dev_drefs(cs->sc_dev) > 1` (ccd.c:1434) is unsatisfiable because cs->sc_dev is the raw device created by make_only_dev(), which takes a permanent creator reference (kern_conf.c:294 reference_dev; destroy_only_dev double-releases at kern_conf.c:316-320). dev_drefs >= 2 even with zero open descriptors, so a configured ccd unit can NEVER be unconfigured: CCDIOCCLR always returns EBUSY (proven with the ioctls own descriptor as the only holder, and via stock ccdconfig -u with fstat showing no holders), CCDF_INITED stays set, component vnodes stay exclusively held, and `kldunload ccd` is denied forever. With fix.diff hunk 2 (disk_getopencount(&cs->sc_disk) > 1, the real per-disk open counter) CCDIOCCLR succeeds, ccdconfig -u succeeds, and the module unloads cleanly.",
  "exploit_chain": "root/operator configures any ccd unit (normal use of the driver) -> unit and its components are wedged until reboot; kldunload ccd denied. Local DoS of the ccd subsystem / permanent resource hold. No memory-corruption chain.",
  "evidence": "run.log (baseline: same-fd CLR EBUSY, separate-fd CLR EBUSY, stock ccdconfig -u EBUSY, kldunload In use, cannot detach, fstat empty); fix_patched.log (patched: CCDIOCCLR ok, ccdconfig -u ok, kldunload ok); VERDICT.md root-cause trail (subr_disk.c:763 -> kern_conf.c:294 -> ccd.c:1434)",
  "kernel_refs": [
    "sys/dev/disk/ccd/ccd.c:1434",
    "sys/kern/kern_conf.c:294",
    "sys/kern/kern_conf.c:316",
    "sys/kern/subr_disk.c:699",
    "sys/kern/subr_disk.c:763",
    "sys/kern/subr_disk.c:1121"
  ],
  "poc_changes": "Authored from scratch during verification (pass-2 discovery); matrix probes A/D from the same session captured in run.log.",
  "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": 40,
  "guest_dirty": 0,
  "build_cmd": "cc -O -o /tmp/df4280 /root/df4280x/trigger.c",
  "run_cmd": "sh /root/df4280x/run.sh   (kldload ccd; vn+label fstype=ccd; SET then same-fd CCDIOCCLR; ccdconfig -u; kldunload)",
  "code_hash": "20086c7707dd8aa6df9b4f5f2adbd2bb4ab24ab3652160f095ef8293cba80ecd",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff hunk 2 replaces dev_drefs(cs->sc_dev) > 1 with disk_getopencount(&cs->sc_disk) > 1. Validated on the patched module: CCDIOCCLR succeeds through the same descriptor, stock ccdconfig -u succeeds, kldunload ccd succeeds; configuration and I/O unregressed (same build as DF-4279 validation).",
  "fix_evidence": "findings/poc/DF-4280/fix_patched.log and run.log (baseline EBUSY vs patched success)",
  "notes": "Discovered live during DF-4279 verification when the control unit could not be torn down. Affects every ccd configuration on this kernel generation (functional regression, unit lockout until reboot).",
  "recommended_fix": "Use disk_getopencount(&cs->sc_disk) > 1 (real open count across whole/slice/partition nodes) instead of dev_drefs() on the raw device, whose count includes the permanent make_only_dev reference."
}