DF-4116 / verdict.json
{ "finding_id": "DF-4116", "status": "reproduced", "reproduced": 1, "impact": "panic", "confidence": "certain", "verdict": "Deterministic kernel panic on sound.ko unload, live-reproduced twice this session with a minimal trigger (kldload sound; kldunload sound \u2014 no snd_hda, no pcm device, no /dev/sndstat open) plus A/B control on one boot (open+close of /dev/sndstat before unload => clean). Root cause: sndstat.c:68 initializes sndstat_buflen=0 (sbuf allocated) while the sbuf is only created by sbuf_new() in sndstat_open(); sound_modevent MOD_UNLOAD (sound.c:1433) acquires-and-never-releases sndstat so the PID guard in sndstat_uninit (sndstat.c:444) always passes on a successful unload, and SNDSTAT_FLUSH (sndstat.c:453) then calls sbuf_delete() on the never-initialized static sbuf -> KASSERT sbuf_delete called with uninitialized or corrupt sbuf (subr_sbuf.c:100), live in the stock X86_64_GENERIC config (INVARIANTS, sys/config/X86_64_GENERIC:56). Resolves the three prior side-observations (DF-4026 panic.sndstat-unload.txt, DF-4115 pack section 5, emu10kx run). Root-only trigger; no memory-safety primitive (no free of attacker data, no UAF); ceiling = reliable admin-action DoS/panic. Fix validated on rebuilt module.", "exploit_chain": "", "evidence": "panic.txt + panic.2.txt (two stock captures, identical trace: sbuf_delete <- sndstat_sysuninit <- linker_file_unload <- sys_kldunload); run.log RUN2 (same-boot A/B: open+close=>clean, no-open=>panic); VERDICT.md 1-5; fix.diff + build.log (patched module, -Werror clean, md5 9422fb6783b984413d3a47ef55d4fbc7): trigger UNLOADED-CLEAN rc=0, 3/3 cycles clean, EBUSY-while-held protection intact", "kernel_refs": [ "sys/dev/sound/pcm/sndstat.c:68", "sys/dev/sound/pcm/sndstat.c:146", "sys/dev/sound/pcm/sndstat.c:151", "sys/dev/sound/pcm/sndstat.c:444", "sys/dev/sound/pcm/sndstat.c:453", "sys/dev/sound/pcm/sndstat.c:466", "sys/dev/sound/pcm/sound.c:1433", "sys/kern/subr_sbuf.c:100", "sys/kern/kern_linker.c:545", "sys/config/X86_64_GENERIC:56" ], "poc_changes": "No seed PoC (finding derived from prior panic notes): wrote minimal trigger.sh; prediction that open+close prevents the panic (verified) and that MOD_UNLOADs acquire makes the PID guard always pass (verified by trace + code reading) were both confirmed live.", "attempts": 3, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 2400, "guest_dirty": 0, "build_cmd": "cd /usr/src/sys/dev/sound/sound && make (after applying fix.diff to /usr/src/sys/dev/sound/pcm/sndstat.c)", "run_cmd": "kldload sound && kldunload sound (baseline: panic; patched: UNLOADED-CLEAN rc=0)", "code_hash": "", "notes": "Trigger even broader than prior notes assumed: no audio hardware or snd_* driver needed. On non-INVARIANTS kernels sbuf_delete no-ops on the zeroed struct and unload succeeds (severity consideration). Guest was vm.sh reset (with-src) after validation.", "recommended_fix": "Initialize sndstat_buflen to -1 (sentinel not allocated) in sys/dev/sound/pcm/sndstat.c:68; validated on rebuilt sound.ko.", "fix_status": "fixed", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "VALIDATED: one-line fix.diff (sndstat_buflen = -1) applied to guest /usr/src, sound.ko rebuilt with -Werror; the exact baseline trigger (kldload/kldunload sound, no sndstat open) returns rc=0 clean instead of panicking; 3/3 repeat cycles clean; unload while /dev/sndstat is held still fails EBUSY by design (no regression).", "fix_evidence": "run.log FIX VALIDATION section; build.log (full -Werror build, sound.ko md5 9422fb6783b984413d3a47ef55d4fbc7); VERDICT.md section 5" } |