From: Cen Zhang <zzzccc427@gmail.com>
To: perex@perex.cz, tiwai@suse.com, sammiee5311@gmail.com,
phucduc.bui@gmail.com, kees@kernel.org,
thomas.weissschuh@linutronix.de, tglx@kernel.org
Cc: linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org,
baijiaju1990@gmail.com, jjzuming@gmail.com, zzzccc427@gmail.com
Subject: [PATCH] ALSA: dummy: Defer hrtimer data freeing until runtime detach
Date: Wed, 14 Oct 2026 13:25:31 +0800 [thread overview]
Message-ID: <pm-pmb-9c80f858ccc13b3de84d-v6-d4059ea2910fe5430f5f@gmail.com> (raw)
The hrtimer record must remain alive while a linked PCM action can
visit its substream. dummy_pcm_close() frees that record before
pcm_release_private() unlinks the substream. runtime->private_data still
points to the freed allocation.
With two configured dummy capture substreams linked and the hrtimer
backend selected, final close drops the group to SETUP. A surviving
peer can then issue PREPARE before the closing substream is unlinked:
Target close Peer PREPARE
snd_pcm_drop(): group -> SETUP
do_hw_free()
dummy_pcm_close(): kfree(dpcm)
snd_pcm_action_nonatomic()
read-lock snd_pcm_link_rwsem
dummy_pcm_prepare()
read dpcm->timer_ops
pcm_release_private()
snd_pcm_unlink(): write-lock
PREPARE holds the link read semaphore and the members' buffer mutexes,
but driver close holds neither across the free. Unlink's write lock
comes too late to protect the record. The ops-pointer read can use freed
memory and dispatch through an invalid function pointer. If PREPARE
already obtained the record before close, dummy_hrtimer_prepare() can
instead write period_time after it has been freed. The report below
shows the dispatch-time read and the ensuing fault; it does not show
the later write.
Defer freeing the hrtimer record to runtime->private_free. Runtime
detach follows unlink, which waits for existing linked PREPARE actions
and prevents new ones from visiting the target. Cancel the embedded
timer in the destructor before releasing its storage. Register the
destructor from the backend free callback so the open error path also
releases the record through runtime detach.
KASAN report as below:
BUG: KASAN: slab-use-after-free in dummy_pcm_prepare+0xb7/0xc0
Read of size 8 at addr ffff888106b35f00 by task alsa_pcm_fixtur/491
Call Trace:
<TASK>
dump_stack_lvl+0x93/0xd0
print_report+0xce/0x630
? dummy_pcm_prepare+0xb7/0xc0
? srso_alias_return_thunk+0x5/0xfbef5
? __virt_addr_valid+0x20d/0x410
? dummy_pcm_prepare+0xb7/0xc0
kasan_report+0xe0/0x110
? dummy_pcm_prepare+0xb7/0xc0
dummy_pcm_prepare+0xb7/0xc0
snd_pcm_do_prepare+0x71/0xb0
snd_pcm_action_group+0x505/0xb30
snd_pcm_action_nonatomic+0xab/0x150
snd_pcm_common_ioctl+0x1bf5/0x3a50
? srso_alias_return_thunk+0x5/0xfbef5
? do_vfs_ioctl+0x1f5/0x1280
? __pfx_do_vfs_ioctl+0x10/0x10
? ioctl_has_perm.constprop.0.isra.0+0x34f/0x500
? __pfx_snd_pcm_common_ioctl+0x10/0x10
? __fput+0x5ba/0xa60
? srso_alias_return_thunk+0x5/0xfbef5
snd_pcm_ioctl+0x76/0xb0
? __pfx_snd_pcm_ioctl+0x10/0x10
__x64_sys_ioctl+0x163/0x1d0
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x41ee8d
Code: 04 25 28 00 00 00 48 89 45 c8 31 c0 48 8d 45 10 c7 45 b0 10 00 00 00 48 89 45 b8 48 8d 45 d0 48 89 45 c0 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 1a 48 8b 45 c8 64 48 2b 04 25 28 00 00 00
RSP: 002b:00007ffcfa72fb60 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 000000000041ee8d
RDX: 0000000000000000 RSI: 0000000000004140 RDI: 0000000000000004
RBP: 00007ffcfa72fbb0 R08: 00007ffcfa72fb98 R09: 0000000000000110
R10: 0000000000000001 R11: 0000000000000246 R12: 00007ffcfa72fcd8
R13: 00007ffcfa72fcf0 R14: 00000000004a8f28 R15: 0000000000000001
</TASK>
Allocated by task 488:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_kmalloc+0xaa/0xb0
__kmalloc_cache_noprof+0x251/0x610
dummy_hrtimer_create+0x4a/0x170
dummy_pcm_open+0xe7/0x730
snd_pcm_open_substream+0x926/0x1580
snd_pcm_open+0x28d/0x6d0
snd_pcm_capture_open+0x82/0xe0
snd_open+0x1ec/0x3e0
chrdev_open+0x21f/0x660
do_dentry_open+0x5c8/0x1300
vfs_open+0x87/0x390
path_openat+0x2460/0x3cd0
do_file_open+0x21e/0x470
do_sys_openat2+0xf4/0x1b0
__x64_sys_openat+0x136/0x1e0
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 490:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x5f/0x80
kfree+0x307/0x580
dummy_hrtimer_free+0x72/0xe0
dummy_pcm_close+0x9f/0xd0
snd_pcm_release_substream.part.0+0x104/0x310
snd_pcm_release+0x106/0x240
__fput+0x39f/0xa60
fput_close_sync+0xff/0x200
__x64_sys_close+0x8c/0xf0
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
==================================================================
Fixes: c631d03c6873 ("ALSA: dummy - Support high-res timer mode")
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
---
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 6b0a06e5c87638264e5d22deda1fe4bc028febe7..ae7cef9d74819a68dcf951a21768dccf38c7c4ad 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -476,13 +476,20 @@ static int dummy_hrtimer_create(struct snd_pcm_substream *substream)
return 0;
}
-static void dummy_hrtimer_free(struct snd_pcm_substream *substream)
+static void dummy_hrtimer_runtime_free(struct snd_pcm_runtime *runtime)
{
- struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
+ struct dummy_hrtimer_pcm *dpcm = runtime->private_data;
+ hrtimer_cancel(&dpcm->timer);
kfree(dpcm);
}
+static void dummy_hrtimer_free(struct snd_pcm_substream *substream)
+{
+ /* Linked PREPARE can still use the data until unlink. */
+ substream->runtime->private_free = dummy_hrtimer_runtime_free;
+}
+
static const struct dummy_timer_ops dummy_hrtimer_ops = {
.create = dummy_hrtimer_create,
.free = dummy_hrtimer_free,
next reply other threads:[~2026-10-14 5:25 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-14 5:25 Cen Zhang [this message]
2026-10-14 7:19 ` Takashi Iwai
2026-10-14 8:35 ` Cen Zhang
2026-10-14 9:07 ` Takashi Iwai
2026-10-14 9:33 ` Cen Zhang
2026-10-14 9:54 ` Takashi Iwai
2026-10-14 10:07 ` Takashi Iwai
2026-10-14 10:19 ` Cen Zhang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pm-pmb-9c80f858ccc13b3de84d-v6-d4059ea2910fe5430f5f@gmail.com \
--to=zzzccc427@gmail.com \
--cc=baijiaju1990@gmail.com \
--cc=jjzuming@gmail.com \
--cc=kees@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=perex@perex.cz \
--cc=phucduc.bui@gmail.com \
--cc=sammiee5311@gmail.com \
--cc=tglx@kernel.org \
--cc=thomas.weissschuh@linutronix.de \
--cc=tiwai@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®