# DF-4344 — atiixp_chip_post_init mixer/pcm_register error-path asymmetry (DF-4156 family, 5th instance)

## What this is

`sys/dev/sound/pci/atiixp.c` orders device bring-up as:

1. `mixer_init(sc->dev, ac97_getmixerclass(), sc->codec)` — atiixp.c:1085 —
   publishes a world-writable (0666) `/dev/mixerN` cdev whose `si_drv1`
   devinfo chain points at the AC97 codec and, through the pcm softc, at
   `sc` (mixer.c:687-737).
2. `pcm_register(...)` — atiixp.c:1087 — can still fail
   (`pcm_veto_load` EINVAL, sound.c:1021-1026; unit > PCMMAXUNIT ENODEV,
   sound.c:1028-1035).
3. On failure: `goto postinitbad` → `atiixp_release_resource(sc)`
   (atiixp.c:1113-1115) → `ac97_destroy(sc->codec)` (atiixp.c:1129-1132,
   kobj_delete + kfree) and `kfree(sc, M_DEVBUF)` (atiixp.c:1165) — while
   the mixer cdev created in step 1 stays registered forever.

The device also *remains attached* (attach already returned 0 — post_init
runs from a `config_intrhook` when cold, atiixp.c:1293-1300), so
`suspend`/`resume` later run against the freed `sc` (`pcm_getdevinfo`
returns the NULL/garbage devinfo left by the failed `pcm_register`;
`atiixp_lock(NULL)` in `atiixp_pci_suspend` atiixp.c:1337 is a NULL-deref
panic), and `detach` never tears the mixer down.

Same construct as the four verified family members:
DF-4156 (maestro), DF-4193 (es137x), DF-4299 (emu10kx-pcm), DF-4334
(via8233). This file is the 5th instance, previously unfiled.

## Reproduce (needs ATI IXP hardware)

Trigger: any machine with an ATI IXP 200/300/400/SB600 AC97 controller
(PCI 1002:4341/4361/4370/4382) where `pcm_register` fails after
`mixer_init` succeeded — e.g. boot with the sound feeder init failed
(`pcm_veto_load` stuck ≠ 0) or unit count above `hw.snd.maxunit`.
Then, as any local user: `open("/dev/mixer0")` + `SNDCTL_MIXER_*` ioctl →
kernel operates on freed `sc`/codec (UAF; mixer dispatch through a
`kobj_delete`d methods table).

Success criterion: use-after-free fault / adjacent-heap corruption in
`mixer_ioctl` paths, or (suspend path) NULL-deref panic in
`atiixp_pci_suspend`.

## On this audit guest

Not runtime-testable: QEMU 7.2 does not emulate the ATI IXP AC97
controller. `guest_check.log` documents: module loads, probe returns ENXIO
for every PCI device, **no pcm device attaches**, so the buggy path never
executes. Source-level certainty only (identical construct to 4 verified
family members).

`panic_df4116_on_atiixp_unload.txt`: incidental capture — unloading
`snd_atiixp` on this guest panics in `sndstat_sysuninit`
(**known, already-filed DF-4116**; not re-reported here). Kept as context:
the module-unload route to exercise teardown is itself blocked by that bug.

## Fix

`fix.diff` — tear the mixer down (which destroys both the cdev and, via
`ac97mix_uninit` → `ac97_destroy`, the codec) before
`atiixp_release_resource`, and keep `release_resource` from destroying the
codec a second time.
