# DF-4227 — VERDICT

**Status: untested** (kernel-side reproduction impossible on this guest —
the device driver attack surface is physically absent; bug is source-certain
and the mechanism is fully traced below).

## What was verified, and how

1. **The module exists and is loadable, but never attaches on this guest.**
   Live on the QEMU guest (run.log / guest-module-lifecycle.log):
   - `make` in `/usr/src/sys/dev/smbus/cyapa` builds `cyapa.ko` cleanly.
   - `kldload` succeeds; the four `debug.cyapa_*` sysctls appear
     (they are module-static, registered at load).
   - `ls /dev/cyapa*` → ENOENT; `pciconf -l` shows no SMBus controller.
   - Reason (source): a cyapa child only exists if an SMBus *address probe*
     succeeded — `smbus_probe_device()` (sys/bus/smbus/smbus.c:120-140) adds
     a child with unit `(smbus_unit << 11) | 0x0400 | addr` only when
     `smbus_trans()` gets a response; `cyapa_probe` (cyapa.c:464) matches
     only unit `0x467`. No controller + no trackpad ⇒ no attach ⇒ no devnode
     ⇒ the read()/write()/kqfilter paths cannot be entered.

2. **The NULL-deref chain is proven from source, line by line:**
   - `cyaparead` cyapa.c:616 `sc = CYAPA_SOFTC(minor(dev))`;
     macro at cyapa.c:389-390 → `devclass_get_softc(cyapa_devclass, unit)`.
   - `devclass_get_softc` (sys/kern/subr_bus.c:932-951) returns NULL once
     `devclass_delete_device` (subr_bus.c:1152-1164) executed
     `dc->devices[dev->unit] = NULL` — which happens inside
     `device_detach()` during `kldunload` via `devclass_delete_driver`
     (subr_bus.c:3648-3655, detach loop at 879-887).
   - `cyaparead` then calls `cyapa_lock(sc)` at cyapa.c:626 with sc==NULL
     (no NULL check — unlike cyapaopen/cyapaclose/cyapaioctl) →
     `lockmgr(&sc->lk, …)` dereferences NULL+offsetof(struct cyapa_softc, lk)
     → page-0 fault → panic.
   - Open fds are not drained by teardown: `cyapa_detach` calls only
     `dev_ops_remove_minor` (cyapa.c:567) → `devfs_destroy_dev_by_ops`
     (sys/vfs/devfs/devfs_core.c:863, worker 1546-1560,
     `devfs_destroy_dev_worker` 1520-1546) which unlinks the node and drops
     refs, but the open file descriptor keeps the cdev alive
     (sys/vfs/devfs/devfs_vnops.c:1366 → sys/kern/kern_device.c
     `dev_dwrite` dispatches via `dev->si_ops` — a static struct in the
     module image, freed by `kldunload`).
   - Readers blocked in `lksleep(&sc->blocked, &sc->lk, PCATCH, "cyablk", 0)`
     (cyapa.c:749) are never woken by `cyapa_detach` (it only wakes
     `&sc->poll_flags`), so they sleep against a dying softc.

3. **Trigger requirements on real hardware:** root (device is 0600
   root:wheel) to open the node and root to `kldunload`. The reader whose
   read() faults may be any process holding the fd (e.g. an fd inherited
   from Xorg by an unprivileged child). Severity accordingly Low
   (already-privileged trigger), memory-corruption class.

## Exploit chain (not developed — hardware-gated)
1. root: open /dev/cyapa0-67 (or inherit fd) → 2. root: kldunload cyapa.ko
   → 3. read(fd) → NULL-deref panic (deterministic), or dispatch through
   freed module memory (if the ops slab is reused: control-flow candidate,
   0x3000-byte module — reuse by kmalloc(M_DRM…)/network slabs is plausible
   on a loaded system but not demonstrated here).

## Recommended fix
- `cyapa_detach`: return EBUSY while `sc->count != 0` (open fds exist), wake
  blocked readers (`wakeup(&sc->blocked)`), `destroy_dev(sc->devnode)`,
  `lockuninit(&sc->lk)`.
- `cyaparead`/`cyapawrite`/`cyapakqfilter`: NULL-check `sc` like the other
  entry points.
See fix.diff.

## Fix validation
Not possible on this guest (device cannot attach; the fix touches attach/
detach paths that are unreachable in QEMU). fix_status = not_testable.

## 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.
