# VERDICT — DF-4551

**Status: not_reproduced** (hardware-gated). **Impact: none on this guest**
(class: local kernel NULL-deref/UAF panic on real hardware — availability
only, no control over data; needs the physical card).

## Root cause (path:line)

Attach window — `als_pci_attach` (als4000.c:808-864) → `als_resource_grab`
(als4000.c:764-806):

1. `sc->irq` allocated **RF_SHAREABLE** (als4000.c:776-777) and
   `snd_setup_intr(dev, sc->irq, INTR_MPSAFE, als_intr, sc, &sc->ih)`
   runs at als4000.c:783-787 — **the handler is live from here on**.
2. `als_init` enables card interrupts: `als_gcr_wr(sc, ALS_GCR_MISC,
   v | 0x28000)` (als4000.c:703-704), and `mixer_init` immediately pokes the
   mixer for every device (mixer.c:713-726 loop calls into `alsmix_set` →
   `als_mix_wr`) — plausibly raising IRQ status bits.
3. The channels the handler dispatches to do not exist yet: `sc->pch` /
   `sc->rch` are zeroed softc members; `ch->channel` is only set by
   `alschan_init` during `pcm_addchan` (als4000.c:852-853, via
   als4000.c:204-232).

`als_intr` (als4000.c:640-677) has **no ownership filter and no NULL
guard**:

```c
intr = als_intr_rd(sc);                      // :646
if (intr & 0x80) { ... chn_intr(sc->pch.channel); }   // :648-651  NULL here
if (intr & 0x40) { ... chn_intr(sc->rch.channel); }   // :654-657  NULL here
```

`chn_intr(c)` (sys/dev/sound/pcm/channel.c:683-694) immediately evaluates
`CHN_LOCKOWNED(c)` → dereferences the NULL `pcm_channel` → panic. Because
the IRQ is shared, another device's interrupt also enters `als_intr` (no
"not mine" early-out — `als_intr_rd` result bits 0x80/0x40 gate only the
channel dispatch, and the handler always ACKs).

Failure paths widen the window: if `mixer_init` or `pcm_register` fails,
`bad_attach` → `als_resource_free` runs late relative to the live handler;
during suspend `als_pci_suspend` calls `als_playback_stop`/`als_capture_stop`
and `als_uninit` under the lock while IRQs are already enabled.

Teardown windows — `als_pci_detach` (als4000.c:866-881):

- `pcm_unregister(dev)` (:872) destroys/frees the `pcm_channel` objects;
  `als_uninit` (:877) disables IRQ *generation* afterwards, and
  `bus_teardown_intr` only happens inside `als_resource_free` (:745-748) —
  an in-flight or shared-line IRQ in that gap dispatches `chn_intr` on
  **freed** channel objects (UAF).
- `als_resource_free` releases the I/O region (:741-744) **before**
  tearing down the interrupt (:745-748); a racing handler then performs
  `bus_space_read_1`/`write_1` (als4000.c:121-145) on a released mapping /
  reallocated port range, and ACKs (`als_intr_wr`) to ports rman no longer
  owns.

## Why not reproduced

No ALS4000 PCI device exists in the QEMU guest (ALS_PCI_ID0 0x40004005 —
guest_hw_evidence.txt); `snd_als4000.ko` loads but `als_pci_attach` and
therefore `snd_setup_intr` never run. There is no QEMU device model for the
ALS4000, so the interrupt cannot be synthesized. Confidence `likely` (the
NULL-window is provable from ordering; the practical trigger needs the card
and a shared/raised IRQ).

## Exploit chain

None beyond panic/DoS (hardware availability race). Not memory corruption
under attacker control.

## Fix validation

not_testable (no hardware).

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