DF-4457 / verdict.json
{ "finding_id": "DF-4457", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "Code defect certain, kernel runtime hardware-gated: cmi_attach() calls mixer_init(dev, &cmi_mixer_class, sc) (cmi.c:986), which publishes a 0666 /dev/mixerN whose si_drv1 -> snd_mixer m has m->devinfo = sc (mixer.c:730-732, mixer.c:78), BEFORE pcm_register(dev, sc, 1, 1) (cmi.c:989). pcm_register can fail (EINVAL via pcm_veto_load sound.c:1021; ENODEV via unit>PCMMAXUNIT=255 sound.c:1027), and the bad: unwind (cmi.c:1004-1016) then destroys the dma tag, tears down the irq, releases resources, snd_mtxfree(sc->lock) and kfree(sc, M_DEVBUF) WITHOUT mixer_uninit(dev) -- the mixer cdev stays registered over freed memory and any unprivileged open/ioctl dispatches cmimix_* through mix_getdevinfo(m) == freed sc (cmi_rd/cmi_wr with a type-confused bus_space tag/handle read out of the freed ~264-byte chunk; the mixers own m->lock survives, so nothing masks the UAF). Identical construct to the verified family DF-4156/4193/4299/4334/4344/4421; this is the 7th instance with the narrowest window (exactly one post-mixer goto: pcm_register). Not runtime-reproducible on the audit guest: QEMU presents no CMedia 13f6 / class-040x PCI function (guest_check.log), and this snapshots snd_cmi.ko itself fails kldload with depends on midi - not available or version mismatch (serial console, run.log), so cmi_attach never executes. Ceiling on real hardware: local unprivileged UAF read/write through a 0666 cdev, gated by an attach-time failure -- Low, matching family precedent.", "exploit_chain": "", "evidence": "VERDICT.md root-cause walk (cmi.c:986-1016, mixer.c:687-764, sound.c:1016-1040); run.log + guest_check.log (no CMedia/audio PCI device, snd_cmi unloadable on snapshot, no /dev/mixer*); build.log (baseline AND fix.diff-patched snd_cmi.ko build -Werror clean, RC=0); fix.diff (git apply --check OK)", "kernel_refs": [ "sys/dev/sound/pci/cmi.c:986", "sys/dev/sound/pci/cmi.c:989", "sys/dev/sound/pci/cmi.c:1004", "sys/dev/sound/pci/cmi.c:1016", "sys/dev/sound/pcm/mixer.c:730", "sys/dev/sound/pcm/sound.c:1021" ], "poc_changes": "no seed; family trigger shape (DF-4334/4344/4421) adapted to cmis single post-mixer failure path; hardware absent so guest gate-check substituted", "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": 900, "guest_dirty": 0, "build_cmd": "cd /usr/src/sys/dev/sound/driver/cmi && make obj && make (baseline + fix.diff-patched, guest cc 8.3, -Werror, RC=0 both)", "run_cmd": "sh run.sh (guest: pciconf shows no 13f6/class-040x device; kldload snd_cmi fails on midi dependency)", "code_hash": "", "notes": "Pass-2 negative results documented in VERDICT.md: cmi_intr NULL-channel window unreachable (channels created within attach at cmi.c:994-995, DMA disabled by cmi_init cmi.c:874-878), getptr modulo safe (sndbuf_resize floors blkcnt*blksz >= 32), dma_prog u16 counts cannot truncate (bufsz<=64K), cmimix_set cmt[dev] bounded by mixer core, resume lock recursion safe (LK_CANRECURSE), mpu401/cmi_midiattach dead code (if(0) at cmi.c:957), detach order correct (pcm_unregister first). Guest /usr/src restored to pristine (md5 3a977e0d\u2026 matches tree); guest left up, no panic, no dirty state.", "recommended_fix": "Move pcm_register() ahead of mixer_init() and pcm_unregister() on the mixer_init failure path so no live cdev remains over freed memory (DF-4334/4421 family shape)", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff (git apply --check OK against pristine tree) reorders pcm_register() before mixer_init() and adds pcm_unregister(dev) when mixer_init() fails (pcm_unregister calls mixer_uninit itself and handles the zero-channel case, sound.c:1146-1215). Compile-validated on the guest: patched snd_cmi.ko builds -Werror clean, RC=0 (build.log). Behavioral baseline/patched runs impossible on this guest: cmi_attach requires CMedia hardware the guest cannot present (fix_status not_testable, compile-validated).", "fix_evidence": "fix.diff; build.log (patched module full compile+link, CMI_BUILD_RC=0); VERDICT.md Fix validation section" } |