# DF-4280 VERDICT

**Status: REPRODUCED (functional lockout / local DoS). Fixed by fix.diff
hunk 2 and re-verified.**

## What was observed (baseline, vulnerable kernel — run.log)
1. Configure a unit via raw ioctl (no I/O at all), close the fd, then
   CCDIOCCLR through a fresh descriptor:
   `CCDIOCCLR: Device busy`.
2. CCDIOCCLR through the SAME still-open descriptor with zero other
   users: `CCDIOCCLR(samefd): Device busy`.
3. Stock `ccdconfig -u ccd0`: `Device busy` with `fstat` showing no
   holder.
4. `kldunload ccd`: `ccd0: In use, cannot detach` — forever.

Once any unit is configured it can never be unconfigured during the
boot: CCDF_INITED stays set, every component vnode stays exclusively
held (ccd.c:1526 `v_opencount > 1` blocks reuse), sc_cinfo/sc_itable/
ii_index stay allocated, the module cannot unload.

## Root cause (path:line)
- sys/kern/subr_disk.c:763 — `_disk_create_named` returns
  `dp->d_rawdev`; ccdattach stores it in `cs->sc_dev`.
- sys/kern/kern_conf.c:294 — `make_only_dev()` ends with
  `reference_dev(devfs_dev)`: a PERMANENT creator reference
  (destroy_only_dev releases twice, kern_conf.c:316-320).
- Therefore `dev_drefs(cs->sc_dev) >= 2` always, and the guard
  **sys/dev/disk/ccd/ccd.c:1434** `if (dev_drefs(cs->sc_dev) > 1)`
  is unconditionally true — CCDIOCCLR can never pass it.

## Fix
fix.diff hunk 2 replaces the guard with
`disk_getopencount(&cs->sc_disk) > 1` — `d_opencount` counts real opens
of every node (whole/slice/partition) of the disk (subr_disk.c:1121/
1150), which is exactly the semantic the guard wanted; in-flight raw
I/O remains covered because the caller's descriptor stays open for the
duration of physread/physwrite.

## Fix validation (patched ccd.ko, same guest, fix_patched.log)
```
[+] CCDIOCSET ok size=16352
[+] CCDIOCCLR ok            <- was EBUSY
ccdconfig -u ccd0 -> ok     <- was EBUSY
kldunload ccd -> ok         <- was "In use, cannot detach"
```
No regression: configuration and I/O still work (DF-4279 control).

## Impact
Not memory corruption. Local denial of service against the ccd
subsystem (units wedge until reboot, module unload denied) by any user
able to open /dev/ccdN for write (root or operator; the nodes are
0640 root:operator). Normal operational pain: ccd reconfiguration
requires a reboot on affected kernels.

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
