β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-4553

snd_vibes: sv_suspend() aborts the playback channel with the record trigger (copy-paste) β€” playback DMA engine left enabled across suspend

Summary

sv_suspend aborts sc->pch with svrchan_trigger (the RECORD channel's trigger); its abort path clears only RECORD_ENABLE, so the playback engine never disables - it keeps bus-mastering across the suspend transition while the framework believes the channel quiesced. PM state-machine defect, no kernel memory-safety impact. One-token fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4553 Β· 7 files
FileTypeDescriptionSize
README.md β€” 2.3 KB ↓ raw
VERDICT.md β€” 2.1 KB ↓ raw
run.sh β€” 146 B view raw
env.txt β€” 418 B view raw
fix.diff β€” 352 B view raw
manifest.json β€” 831 B view raw
verdict.json β€” 2.1 KB view raw

DF-4553 β€” sv_suspend() aborts the playback channel with the record trigger (copy-paste): playback DMA engine left running across suspend

What this is

sys/dev/sound/pci/vibes.c:653, inside sv_suspend():

    sc->rch.dma_was_active = sc->rch.dma_active;
    svrchan_trigger(NULL, &sc->rch, PCMTRIG_ABORT);   /* correct: rec */

    sc->pch.dma_was_active = sc->pch.dma_active;
    svrchan_trigger(NULL, &sc->pch, PCMTRIG_ABORT);   /* BUG: play channel
                                                         * aborted with the
                                                         * RECORD trigger */

svrchan_trigger()'s STOP/ABORT path (vibes.c:345-350) clears SV_RECORD_ENABLE and stops DMAC β€” it never touches the playback engine. Applied to sc->pch it does nothing to the playback DMA: SV_PLAY_ENABLE stays set, so DMAA keeps bus-mastering the (still mapped and armed) DMA buffer while the system suspends, and the record engine is disabled twice. On sv_resume() the playback channel is then re-programmed and restarted as if it had been cleanly stopped.

Consequences on real hardware: the S3 SonicVibes continues to master PCI bus traffic into ch->buffer across the suspend transition β€” the driver believes the channel is stopped. This is a suspend/resume state-machine defect (upstream FreeBSD's driver uses svpchan_trigger for the playback channel); security impact is bounded to device/PM misbehavior (continued DMA, noise, corrupted stream state on resume), not kernel memory corruption.

Reproduce

Needs an S3 SonicVibes (5333:ca00) machine playing audio:

  1. cat /dev/dsp0 < /dev/zero & (playback running)
  2. acpiconf -z / suspend-to-RAM
  3. Observe (via the card's status register, SV_CM_STATUS_AINT still firing / audio path still live) that playback DMA was never disabled.

Expected after fix: playback engine disabled at suspend (SV_PLAY_ENABLE cleared via svpchan_trigger).

What was run on the audit QEMU guest

No SonicVibes hardware (pciconf -l | grep 5333 β†’ none; /dev/sndstat empty with snd_vibes.ko loaded) β€” suspend/resume of this device cannot be exercised. not_reproduced on this guest; the defect is visible by inspection and is a one-token fix.

Verdict

not_reproduced β€” hardware absent. Source-level: certain.

VERDICT.md
↓ download raw

DF-4553 VERDICT β€” not_reproduced (hardware absent); source-level: certain, one-token fix

Root cause

sv_suspend() (sys/dev/sound/pci/vibes.c:644-659) saves each channel's dma_active state and aborts it. Line 653 aborts the playback channel sc->pch with svrchan_trigger() β€” the record channel's trigger β€” a copy-paste of the line above it. svrchan_trigger()'s PCMTRIG_STOP/PCMTRIG_ABORT arm (vibes.c:345-350) clears SV_RECORD_ENABLE only; the playback enable (SV_PLAY_ENABLE, SV_REG_ENABLE bit) is left set, so DMAA remains armed and bus-mastering while the machine suspends. The record engine gets disabled twice (harmless) and the playback engine not at all.

sv_resume() (vibes.c:661-687) later re-runs svpchan_trigger(0, &sc->pch, PCMTRIG_START) only if (sc->pch.dma_was_active) β€” i.e. it papers over the stale-enable state by reprogramming, but between suspend entry and resume the device is in a state the driver does not model (continued DMA into a buffer the sound framework considers quiesced; continued interrupt generation feeding chn_intr(sc->pch.channel) while the pcm layer is suspended).

Why not reproduced here

The audit QEMU guest has no S3 SonicVibes (PCI 5333:ca00) device: pciconf -l | grep 5333 empty; with snd_vibes.ko loaded, /dev/sndstat reports zero installed devices (see DF-4552 run.log). Suspend/resume of the device therefore cannot be driven. No kernel-memory impact is claimed; the finding is a device state-machine / PM defect with a one-token fix.

Fix

vibes.c:653: svrchan_trigger(NULL, &sc->pch, PCMTRIG_ABORT); β†’ svpchan_trigger(NULL, &sc->pch, PCMTRIG_ABORT); (matches upstream FreeBSD, whose snd_vibes uses the playback trigger for the playback channel in sv_suspend). See fix.diff.

Fix status (batch validation)

Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.

Fix verification

not_testable
baseline no→ patch + rebuild →patched clean

Not testable: no SonicVibes hardware in the QEMU guest; fix is a one-token correction identical to upstream FreeBSD's driver

fix.diff
↓ fix.diffper-fix-DF-4553

Confirmed kernel references

Detail

Evidence (decisive lines)

vibes.c:653 svrchan_trigger on &sc->pch; svrchan_trigger STOP/ABORT arm at vibes.c:345-350 touches only SV_RECORD_ENABLE; contrast svpchan_trigger STOP/ABORT at vibes.c:422-427 which clears SV_PLAY_ENABLE

PoC changes

authored from scratch this pass (no seed; finding filed this pass)

Verified recommended fix

vibes.c:653: use svpchan_trigger for sc->pch in sv_suspend (see fix.diff)

Verdict

Copy-paste defect at vibes.c:653: sv_suspend() aborts sc->pch (playback) with svrchan_trigger (the RECORD trigger), which only clears SV_RECORD_ENABLE (vibes.c:345-350). The playback DMA engine (DMAA) is therefore never disabled at suspend and keeps bus-mastering while the system suspends; the record engine is disabled twice. Not reproduced on the audit guest: no 5333:ca00 PCI device exists there, so the device suspend path cannot be exercised. Security impact bounded to device/PM misbehavior (continued DMA across suspend, stale-enable state on resume); no kernel memory-safety impact.