# DF-4552 — snd_vibes attach-failure paths leave a live 0666 /dev/mixerN over released bus resources (DF-4156 family, 12th instance)

## What this is

`sv_attach()` (sys/dev/sound/pci/vibes.c) publishes the mixer at line 789
(`mixer_init(dev, &sv_mixer_class, sc)`), which — see
sys/dev/sound/pcm/mixer.c:730-733 — `make_dev()`s a **mode 0666**
`/dev/mixerN` cdev whose `si_drv1->devinfo` is the driver softc `sc`.
Four later failure paths

* vibes.c:815-821 resource-assumption check (`goto fail`)
* vibes.c:837-840 dmaa allocation (`goto fail`)
* vibes.c:856-859 dmac allocation (`goto fail`)
* vibes.c:872-875 `pcm_register` failure (`goto fail`)

unwind with `fail:` (vibes.c:888-901): the DMA tag is destroyed, the
interrupt is torn down and **all** bus resources (enh/dmaa/dmac) are
released — but `mixer_uninit()` is never called (`pcm_unregister()`, the
only caller of `mixer_uninit` — sound.c:1205 — is never reached on a failed
attach, and even a hypothetical later `pcm_unregister` would return early
because `PCM_ALIVE(d)` is false for a never-registered device). `sc` itself
is also leaked (no `kfree`, including the early ENXIO return at
vibes.c:746-749).

Result: after a post-`mixer_init` attach failure, `/dev/mixerN` stays
world-RW with `devinfo = sc` whose cached `bus_space_tag/handle` pairs point
at I/O port ranges rman no longer owns. Any local user (device is 0666
root:wheel) issuing mixer ioctls drives `sv_mix_set()` →
`sv_indirect_get/set()` → `bus_space_read/write_1` on released ports, which
rman may have re-allocated to a different PCI device.

This is the 12th instance of the sound-family mixer-UAF/unwind-asymmetry
family: DF-4156, DF-4193, DF-4299, DF-4334, DF-4344, DF-4421, DF-4457,
DF-4468, DF-4504, DF-4537, DF-4550.

## Reproduce (on hardware)

1. Machine with an S3 SonicVibes (PCI 5333:ca00).
2. Force `sv_attach()` to fail after `mixer_init()` — e.g. make the
   midi/games port-gap assumption fail (vibes.c:815-821) by having the PCI
   BIOS lay out the MIDI/GAMES BARs such that the gap is >= 0x800 or not
   0x200-aligned, or patch a failure injection at vibes.c:874.
3. As an unprivileged user: `cc -O -o mixer_probe mixer_probe.c && ./mixer_probe /dev/mixer0`
   — the MIXER_WRITE ioctl reaches `sv_mix_set()` over released ports.

## What was run on the audit QEMU guest (2026-09-21)

The guest has **no** SonicVibes device (`pciconf -l | grep 5333` → no
match), so `sv_attach` never runs and the failure window cannot be entered.
The probe was built on the guest and run anyway, as root and as an
unprivileged user, to document the honest result:

```
/tmp/mixer_probe /dev/mixer0  →  open: No such file or directory   (no mixer0 published)
/tmp/mixer_probe /dev/mixer   →  open: Bad file descriptor         (default clone; zero pcm units registered → mixer_clone ENODEV path)
```

with `snd_vibes.ko` loaded (`kldload snd_vibes`), `/dev/sndstat` showing
`Installed devices:` (empty). Logs: `build.log`, `run.log`.

## Verdict

`not_reproduced` — the defect is certain at source level (same proven
family pattern as 11 accepted instances), but this guest has no SonicVibes
PCI hardware, so the trigger cannot be entered. See `VERDICT.md`.
