โฌข DragonFlyBSD Kernel Audit
DF-4551 / als_intr_window.c
โ† back to finding โ†“ download raw
/* DF-4551 โ€” als_intr() NULL/dangling channel-state window proof-of-concept.
 *
 * sys/dev/sound/pci/als4000.c orders its lifetime badly:
 *
 *   als_resource_grab()  :783  snd_setup_intr(als_intr)   <- handler live
 *   als_init()           :704  GCR_MISC |= 0x28000        <- IRQs enabled
 *   ... mixer_init/pcm_register run ...
 *   pcm_addchan          :852  sc->pch.channel still NULL until alschan_init
 *
 * Any interrupt in that window (shared line โ€” the IRQ is allocated
 * RF_SHAREABLE at :777 โ€” or the card itself asserting during mixer_init's
 * register writes) takes the (intr & 0x80)/(intr & 0x40) branches at
 * :648-658 into chn_intr(sc->pch.channel == NULL) -> CHN_LOCKOWNED(c) on a
 * NULL pcm_channel (channel.c:683-694) -> kernel NULL-deref panic.
 *
 * Symmetrically on teardown, pcm_unregister() (:872) destroys the channel
 * objects while the handler stays registered until als_resource_free()
 * (:745-748), and the I/O region is released (:742) BEFORE the interrupt is
 * torn down โ€” a racing IRQ runs the handler over freed channels and a
 * released bus_space mapping.
 *
 * This program documents the exerciser: it cannot run on the QEMU guest
 * because there is no ALS4000 PCI device there (guest_hw_evidence.txt), so
 * snd_setup_intr/als_intr are never invoked. The trigger on real hardware
 * is simply "have the card share its IRQ line with a busy device and
 * load/unload snd_als4000" โ€” no privileges needed beyond a device that
 * raises interrupts on the shared line while the module attaches/detaches.
 *
 * Compile-check only on the guest:
 *   cc -Wall -c als_intr_window.c
 */
int als_intr_window_poc_placeholder;	/* documentation artifact */