# DF-5103 VERDICT

**Status: untested (Low severity, root-coordinated race — verification
skipped per the audit contract). Mechanism source-certain.**

## The window, traced

1. `apple_fw_attach` → `apple_fw_sysctl_init(dev)` (apple_fw.c:144) adds
   oids into the **device-managed** ctx (`device_get_sysctl_ctx`,
   apple_fw_sysctl.c:28) whose `arg1` pointers target softc fields:
   `&sc->sc_osdw` (:32-34), `&sc->sc_ssdt_count` (:37-39),
   `sc->sc_ssdts[i].oem_table_id` (:47-50), `ddev->name/path/sval/bval`
   (:69-121). All `CTLFLAG_RD` — world-readable.

2. On removal, `device_detach` (subr_bus.c:2130) calls the driver's
   `apple_fw_detach` (apple_fw.c:149-156 — a bare `lockuninit`, no sysctl
   teardown), then:

   ```
   subr_bus.c:2149  device_set_driver(dev, NULL);
        └─ subr_bus.c:1941-1947: kfree(dev->softc)   <-- softc FREED
   subr_bus.c:2151  device_sysctl_fini(dev);
        └─ subr_bus.c:238: sysctl_ctx_free(&dev->sysctl_ctx)  <-- oids removed
   ```

3. Readers: `userland_sysctl` wraps `sysctl_root` in `SYSCTL_SLOCK()`
   (kern_sysctl.c:1572-1576); handlers run under that shared lock.
   `sysctl_unregister_oid` requires `SYSCTL_XLOCK` (kern_sysctl.c:70-76).
   Nothing takes the sysctl lock between (2)'s two statements, so a reader
   can acquire the SLOCK, resolve a still-registered oid, and run its
   handler against the already-freed softc.

4. Consequence: string oids read freed heap until a NUL (leak of reused
   slab contents to an unprivileged caller); OPAQUE oids copy `val_len`
   bytes captured at registration (apple_fw_sysctl.c:116-120) out of freed
   memory; INT/QUAD oids read freed scalars. The freed chunk is ~330KB
   (64 × sizeof(struct apple_fw_dsm_dev) ≈ 64 × 5.4KB + 32×9B SSDT ids),
   a very reusable allocation.

## Why not reproduced

Requires root to initiate the unload while an unprivileged process lands a
sysctl read in a microsecond-scale window; classified Low, and the contract
exempts Low findings from mandatory guest verification. The ordering defect
itself is unambiguous from source; no dynamic behavior could contradict it.

## Not re-reported / related

- DF-4773 (apple_smc): same family, longer window (oids outlive detach
  until device_delete), rated Medium there.
- The generic half of this bug (device_set_driver frees softc before
  device_sysctl_fini) affects every driver that registers softc-backed
  oids in the device ctx; this finding is filed against apple_fw because
  its ~330KB softc surface makes it the concrete instance audited here.

## Fix

`fix.diff`: driver-owned sysctl ctx freed in `apple_fw_detach` before the
softc is released by newbus. (The belt-and-braces kernel-wide fix —
reordering `device_sysctl_fini` before `device_set_driver` in
`device_detach` — is noted in the finding markdown but out of this file's
scope.)

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