# DF-4293 — `mixer_reinit` / `mixer_hwvol_*` dereference the mixer cdev pointer with no NULL guards (driver-lifecycle NULL-deref panic)

Pass-2 finding for `sys/dev/sound/pcm/mixer.c` (0666 `/dev/mixerN` core).
The pass-2 brief's families (a) dispatch bounds, (b) name-table walks,
(c) volume packing, (e) count refresh, (f) sndstat — were audited and
found **clean** (see VERDICT.md negative-space section, backed by the
live hostile-ioctl battery in this pack). The one real defect is the
unguarded device-lifecycle path below.

## The bug

`mixer.c` functions consumed by sound drivers at resume/reinit time fetch
the mixer cdev and dereference it with no checks:

| Function | Lines | Unguarded deref |
|---|---|---|
| `mixer_reinit` | `mixer.c:828-830` | `m = pdev->si_drv1;` (pdev and si_drv1 both unchecked) |
| `mixer_hwvol_init` | `mixer.c:881-882` | same |
| `mixer_hwvol_mute` | `mixer.c:915-916` | same |
| `mixer_hwvol_step` | `mixer.c:955-956` | same |

`mixer_get_devt()` (mixer.c:117-125) returns `snddev->mixer_dev`, which
is NULL whenever `mixer_init()` failed (e.g. the driver's `MIXER_INIT`
method returned an error — `mixer_obj_create` mixer.c:644-649 then
returns NULL and `mixer_init` returns -1 **without creating the cdev**,
mixer.c:709-711) or the device is mid-teardown (`mixer_uninit` NULLs
`d->mixer_dev` at mixer.c:814).

The in-file precedent for the required guard is `mixer_uninit` itself
(mixer.c:776: `if (d == NULL || pdev == NULL || pdev->si_drv1 == NULL)
return EBADF;`) — the four functions above simply omit it.

Callers are driver resume/reinit handlers, e.g.
`sys/dev/sound/pci/als4000.c:909`, `cmi.c:1075`, `solo.c:965`,
`vibes.c:673`, `cs4281.c:935`, `sys/dev/sound/pci/hda/hdaa.c:6576`.
A driver whose mixer failed to initialize (misbehaving codec / failed
`MIXER_INIT`) that then resumes or reinits its channels calls
`mixer_reinit(dev)` → `pdev->si_drv1` with `pdev == NULL` →
`Fatal trap 12` kernel panic (CWE-476). This is the pcm-core-side
expression of the DF-4156/4193 "driver misbehaves at init" family the
pass-2 brief asked to hunt.

## Threat model / severity

Trigger requires a driver lifecycle event (Suspend/Resume — root via
`acpiconf`/ACPI, or devd-driven reinit) on hardware whose mixer_init
failed, i.e. privileged or hardware-dependent — hence **Low**, not a
0666-device attack. The 0666 ioctl surface itself was hammered live
(see run.log / run.2.log) and is clean.

## Reproduce

Code-trace certain; not triggerable on this guest (single ES1370 card
with a healthy mixer; suspend/resume not exercisable in this QEMU setup).
The pack instead live-verifies the negative space: two hostile ioctl
batteries against /dev/mixer0 + /dev/dsp0 as uid 1001 — all 256 device
bytes read+write, hostile recsrc/mixerinfo/audioinfo payloads, and
~1M concurrent mixer operations — zero panics, zero unexpected errnos.
