AIOGCAP ioctl dereferences d->mixer_dev without NULL check, causing kernel panic
Summary
AIOGCAP handler at dsp.c:1311-1313: pdev=d->mixer_dev, then p->inputs=pdev->si_drv1?mix_getdevs(pdev->si_drv1):0. Ternary only guards pdev->si_drv1 not pdev itself. pdev->si_drv1 derefs NULL+offsetof(si_drv1) if mixer_dev==NULL. All other ioctls guard (dsp.c:1124/1852/1865/2760). mixer_dev=NULL: mixer_init failed, or mid-detach after mixer_uninit. /dev/dsp is 0666. Fix: check (pdev!=NULL && pdev->si_drv1!=NULL).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1260 Β· 12 files| File | Type | Description | Size | |
|---|---|---|---|---|
| trigger.c | trigger-source | opens /dev/dsp, issues AIOGCAP; reports unreachability on guest | 1.7 KB | view raw |
| fix.diff | suggested-fix | guard pdev != NULL in AIOGCAP | 733 B | view raw |
| build.sh | repro-script | build trigger | 337 B | view raw |
| run.sh | repro-script | run trigger (sound.ko must be loaded) | 317 B | view raw |
| build.log | build-log | trigger build output | 14 B | view raw |
| run.log | run-log | open(/dev/dsp) fails: no pcm device | 161 B | view raw |
| VERDICT.md | verdict | full source-level trace + fix rationale | 3.0 KB | β raw |
| env.txt | environment | guest uname, PCI (no audio), sound.ko load test | 1.7 KB | view raw |
| fix_build.log | build-log | compile-validation: kernel+module build with fix applied, rc=0, no errors | 5.6 MB | β download |
| README.md | readme | human reproduce doc | 707 B | β raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-1260 PoC β AIOGCAP NULL-deref on d->mixer_dev (LATENT on guest; source-confirmed)
Status: source-confirmed real; NOT reproducible on audit guest (no audio HW).
Impact: NULL-deref panic (DoS) via ioctl(AIOGCAP) on /dev/dsp when a pcm
device has mixer_dev==NULL (mixer_init failed / detach race).
Driver: sys/dev/sound/pcm/dsp.c (sound subsystem; loads as module but no HW attaches).
Reproduce
# load sound subsystem (creates /dev/dsp but no pcm device registers without HW): ssh dfbsd 'kldload sound.ko' ./build.sh && ./run.sh # reports open(/dev/dsp) failure: no audio hardware
The bug needs real audio HW + a mixer-less pcm device. See VERDICT.md + fix.diff.
DF-1260 β AIOGCAP NULL-deref on d->mixer_dev (LATENT on audit guest; source-confirmed)
Verdict
NOT REPRODUCED on the audit guest (LATENT / HW-gated). The bug is
confirmed real by source-level trace; it cannot fire on this guest
because no audio hardware attaches, so /dev/dsp cannot be opened and the
AIOGCAP handler is never reached.
Mechanism (confirmed in source)
dsp.c:1311pdev = d->mixer_dev;(no NULL check)dsp.c:1313p->inputs = pdev->si_drv1 ? mix_getdevs(pdev->si_drv1) : 0;The ternary guardspdev->si_drv1but notpdevitself. Ifd->mixer_dev == NULL(mixer_init failed, or mid-detach aftermixer_uninit), the readpdev->si_drv1dereferencesNULL + offsetof(struct cdev, si_drv1)β fatal trap.- Every sibling ioctl in the same file guards it:
dsp.c:1124,dsp.c:1852,dsp.c:1865,dsp.c:2760all doif (d->mixer_dev != NULL). Only AIOGCAP (1311-1313) forgets to. /dev/dspis mode0666(crw-rw-rw-), so reaching it from an unprivileged user is trivial once a pcm device with a NULL mixer exists.
Why it does not reproduce here
kldload sound.kosucceeds and creates/dev/dsp(0666), BUTpciconf -lvshows no multimedia/audio class device; nosnd_*PCI bridge driver attaches, so zero pcm devices are registered (/dev/sndstatis empty).- With no registered pcm device,
open("/dev/dsp", O_RDWR)returns fd=-1 (EBADF on DragonFly), so the AIOGCAP handler β which operates on asnddev_info dobtained from an open pcm cdev β is never entered. - Reaching the bug needs: real audio HW + a
snd_*driver that registers a pcm device whosemixer_initfailed (or a detach race leavingmixer_dev==NULL).
This is a valid hard blocker for live reproduction: the path is unreachable at runtime on this guest and no userspace action exercises it without audio HW.
Exploit chain
N/A β NULL-deref panic (DoS), HW-gated (latent). No write primitive, no
escalation chain. Realistic threat: a local unprivileged user on a machine
whose audio driver registered a mixer-less pcm device (or racing a detach)
triggers a kernel panic via a single ioctl(AIOGCAP) on /dev/dsp.
PoC changes
trigger.c opens /dev/dsp and attempts ioctl(AIOGCAP); on this guest it
reports the open failure (no pcm device). The trigger documents the path; the
fix is the deliverable.
Fix (fix.diff)
Guard pdev itself, not only pdev->si_drv1 β matching the sibling ioctls:
p->inputs = (pdev != NULL && pdev->si_drv1 != NULL)
? mix_getdevs(pdev->si_drv1) : 0;
Applies cleanly (patch -p1 rc=0). Matches the finding proposal.
Fix validation
See fix_build.log / fix_run.log. A sound-enabled kernel (DF1260 config =
X86_64_GENERIC + device sound) was built with the fix applied to confirm
the patched dsp.c compiles cleanly. The bug itself is not triggerable on the
guest (no audio HW), so there is no live before/after; fix_status=not_testable
per the latent-bug rule, with compile validation.
Fix verification
not_testablecompile validated
kernel/module build rc=0
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. dsp AIOGCAP mixer_dev no NULL guard (siblings do) -> NULL+offsetof deref. sound module, no audio HW.
No comments yet.