`snd_card_asihpi_runtime_free()` frees the per-open `struct snd_card_asihpi_pcm` while a polled timer callback or an IRQ/threaded handler can still use it. The polled stop path uses `timer_delete()` (not `timer_delete_sync()`), and the IRQ stop path clears `card->llmode_streampriv` without `synchronize_irq()`. A normal PCM close can therefore free `dpcm` and then `runtime` while the callback is still running. The detailed description: * Test environment / affected version Linux 7.3.0 source plus a QEMU/KASAN fake-PCM harness. No ASI6205 hardware was available; the harness validates the ALSA core close ordering and the exact `timer_delete`/`llmode_streampriv` lifetime pattern. * Mechanism `snd_card_asihpi_runtime_free()` (`asihpi.c:495-499`) does `kfree(dpcm)` and is installed as `runtime->private_free` at playback open (`asihpi.c:997-1000`) and capture open (`1166-1169`). Polled mode: snd_card_asihpi_pcm_timer_start() asihpi.c:501-513 mod_timer(&dpcm->timer, jiffies + expiry); dpcm->respawn_timer = 1; snd_card_asihpi_pcm_timer_stop() asihpi.c:515-522 dpcm->respawn_timer = 0; timer_delete(&dpcm->timer); /* no sync */ `snd_card_asihpi_timer_function()` (`asihpi.c:710-896`) uses `dpcm` throughout and can re-arm at 894-895 if it observes `respawn_timer`. IRQ mode: snd_card_asihpi_pcm_int_start() asihpi.c:524-538 card->llmode_streampriv = dpcm; ... set HPI IRQ rate ... snd_card_asihpi_pcm_int_stop() asihpi.c:540-550 ... set HPI IRQ rate 0 ... card->llmode_streampriv = NULL; /* no synchronize_irq */ `snd_card_asihpi_isr()` (`asihpi.c:898-907`) reads `asihpi->llmode_streampriv` twice (check, then dereference), so a threaded handler can hold the old `dpcm` pointer across the NULL store. Close path: `snd_pcm_release_substream()` (`sound/core/pcm_native.c:2785-2805`) -> `snd_pcm_drop()` (`pcm_native.c:2267-2289`) -> `snd_pcm_detach_substream()` (`sound/core/pcm.c:978-1005`) -> `runtime->private_free()` -> `kfree(dpcm)` and then `kfree(runtime)`. * Trigger model Local user opens a capture or playback PCM, starts it, and closes it while the polled timer or HPI IRQ is active. Polled mode is available on HPI6000 and HPI6205; IRQ mode requires HPI6205 in interrupt mode. SMP/preemption needed for the cross-CPU window. Consequence: UAF of `dpcm`/`runtime` in timer softirq or threaded IRQ; crash or memory corruption. * Dynamic evidence `sndpci_race.c` mode `pcm`, `verification/kmod/ sndpci/pcmtest.c close 200`: `.trigger STOP` uses `timer_delete()` and `runtime->private_free` frees `dpcm`; timer pinned to CPU0, user close to CPU1. Contain 35 KASAN UAF report fragments: BUG: KASAN: slab-use-after-free in race_pcm_timer ... Allocated by task: race_pcm_open Freed by task: kfree -> snd_pcm_detach_substream -> snd_pcm_release * Suggested direction In `snd_card_asihpi_runtime_free()` (or immediately before it), for polled mode call `timer_shutdown_sync(&dpcm->timer)`. For IRQ mode, first clear `card->llmode_streampriv` (with the appropriate ordering), then `synchronize_irq(card->hpi->irq)` before `kfree(dpcm)`. Do not put the sleeping sync inside the PCM stream lock; do it in the detach/private_free process context. Also consider quiescing before the HPI stream `.close` (the extra HPI stream handle window is discussed in the report). Please keep me in Cc; I am not subscribed to the lists. Regards, Hanxiang Xu xuhx@hust.edu.cn