# DF-4743 — via82c686: attach-failure paths after mixer_init() leave the live 0666 /dev/mixerN over the freed codec — mixer-UAF family, 16th instance (DF-4156/4193/4299/4334/4344/4421/4457/4468/4504/4537/4550/4552/4610/4651/4724)

## Where

`via_attach()` publishes the mixer at line 548:

```c
via->codec = AC97_CREATE(dev, via, via_ac97);      /* via82c686.c:544 */
if (!via->codec)
        goto bad;

if (mixer_init(dev, ac97_getmixerclass(), via->codec))   /* :548 -> /dev/mixerN */
        goto bad;
```

`mixer_init()` does `make_dev(&mixer_ops, ..., 0666, "mixer%d", unit)` and
stores the codec as the mixer's `devinfo` (`pdev->si_drv1 = m`,
`m->devinfo = devinfo` — sys/dev/sound/pcm/mixer.c:709,730-733,
mixer.c:635). After that point `via_attach()` keeps **five failure paths**:

- `bus_dma_tag_create(parent_dmat)`      — via82c686.c:556-565
- `bus_dma_tag_create(sgd_dmat)`         — via82c686.c:572-582
- `bus_dmamem_alloc(sgd_table)`          — via82c686.c:584-586
- `bus_dmamap_load(sgd_dmamap)`          — via82c686.c:587-589
- `pcm_register(dev, via, 1, 1)`         — via82c686.c:596

The `bad:` unwind then runs

```c
if (via->codec) ac97_destroy(via->codec);   /* :602 — kobj_delete + kfree(codec) (ac97.c:852-858) */
...
if (via) kfree(via, M_DEVBUF);              /* :611 */
```

with **no `mixer_uninit(dev)`** anywhere. DragonFly newbus never detaches a
failed attach, so the world-writable `/dev/mixerN` cdev stays registered,
its `si_drv1 -> m -> devinfo` pointing at the freed codec, and through
`via_ac97` methods at the freed `via` (bus_space handle, lock — the lock
itself was `snd_mtxfree`d at :610). Any unprivileged user opening the node
and issuing a mixer ioctl reaches `via_read_codec`/`via_write_codec`
(via82c686.c:180-209) over freed memory → UAF read/write.

Family premise (failed attach leaves live 0666 cdev reachable by
unprivileged open) was already **dynamically verified on this same guest
kernel** by the DF-4724 evidence run (make_dev-then-fail KLD:
`/dev/premtest0` persisted 0666 after "attach returned 6"; uid=1001
`open()` returned 0 and reached module code — findings/poc/DF-4724/).

## Guest reachability facts (live, this run — see run.log)

- `snd_via82c686.ko` ships in `/boot/kernel` (unlike aureal, DF-4724,
  which was unwired): `sys/conf/files:2156` and
  `sys/dev/sound/driver/Makefile:5` both wire it.
- `kldload snd_via82c686` succeeds on the audit guest; with no VIA
  686A on the PCI bus nothing attaches, no `mixer0` unit is created —
  the UAF trigger requires the physical card + one attach failure after
  line 548.

## Fix

Call `mixer_uninit(dev)` on every failure after `mixer_init()` succeeds
(see fix.diff) — same idiom as the family fix in DF-4724.
