# DF-4299 verdict

## Reproduced?
No — not testable on this guest. `snd_emu10kx_pcm` binds to the
`emu10kx` bridge driver, which probes for Creative EMU10K1/EMU10K2 PCI
chipsets (emu10kx.c PCI IDs). The audit guest (QEMU virtio/ATI-less) has
no such device; the module has nothing to attach to, so the trigger
cannot be reached at runtime here (`kldload snd_emu10kx` would simply
find no hardware). Status: `untested`, analysis-only.

## Root cause (path:line)
- `sys/dev/sound/pci/emu10kx-pcm.c:1399` — `mixer_init(dev,
  &emudspmixer_class, sc)` registers `sc` as the mixer's persistent
  devinfo (sound.c `mixer_init` stores it; `mix_getdevinfo()` returns it
  to every mixer ioctl).
- `sys/dev/sound/pci/emu10kx-pcm.c:214` — for RT_FRONT the mixer init
  callback also `mixer_create()`s an AC97 submixer stored in `sc->sm`.
- `sys/dev/sound/pci/emu10kx-pcm.c:1455-1470` — after mixer_init, only
  `emu_pcm_init()` (always returns 0, line 1285-1290) and
  `pcm_register()` (line 1467) can still fail; `pcm_register` fails on
  `pcm_veto_load` (sound.c:1021-1027) or `device_get_unit(dev) >
  PCMMAXUNIT` (sound.c:1030-1035).
- `sys/dev/sound/pci/emu10kx-pcm.c:1488-1494` — `bad:` path:
  `ac97_destroy(sc->codec)` + `snd_mtxfree(sc->lock)` + `kfree(sc)` —
  no `mixer_uninit(dev)`, no `mixer_delete(sc->sm)`.

Consequence: `/dev/mixerN` remains registered (created by the sound core
inside mixer_init) with `m->devinfo == freed sc`; the next mixer ioctl
(e.g. `MIXER_CMD`/OSS mixer write) runs `emu_dspmixer_set()` on freed
memory: reads `sc->route`, dereferences `sc->sm`/`sc->card`, writes DSP
registers through `emumix_set_volume(sc->card, ...)` (sc->card freed
pointer load) → kernel UAF (read + effectively arbitrary indirect
register-write path), plus the submixer leak.

## Threat
Requires the sound card present and an attach-time failure after
mixer_init — i.e. `pcm_register()` failing. Not attacker-schedulable in
general (unit exhaustion / prior pcm error), hence Low severity, but the
resulting UAF is on the standard mixer ioctl path.

## Fix
```diff
--- a/sys/dev/sound/pci/emu10kx-pcm.c
+++ b/sys/dev/sound/pci/emu10kx-pcm.c
@@ -1485,6 +1485,9 @@ emu_pcm_attach(device_t dev)
 	return (0);
 
 bad:
+	if (sc->ihandle >= 0)
+		(void)emu_intr_unregister(sc->card, sc->ihandle);
+	if (mixer_inited)
+		(void)mixer_uninit(dev);
 	if (sc->codec)
 		ac97_destroy(sc->codec);
 	if (sc->lock)
```
(with a local `int mixer_inited = 0;` set to 1 after each successful
`mixer_init()` call; the ihandle unregister line closes the DF-1506
attach-failure half.)

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