From: Takashi Iwai <tiwai@suse.de>
To: Cen Zhang <zzzccc427@gmail.com>
Cc: perex@perex.cz, tiwai@suse.com, sammiee5311@gmail.com,
phucduc.bui@gmail.com, kees@kernel.org,
thomas.weissschuh@linutronix.de, tglx@kernel.org,
linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org,
baijiaju1990@gmail.com, jjzuming@gmail.com
Subject: Re: [PATCH] ALSA: dummy: Defer hrtimer data freeing until runtime detach
Date: Wed, 14 Oct 2026 09:19:40 +0200 [thread overview]
Message-ID: <877bjkg35f.wl-tiwai@suse.de> (raw)
In-Reply-To: <pm-pmb-9c80f858ccc13b3de84d-v6-d4059ea2910fe5430f5f@gmail.com>
On Wed, 14 Oct 2026 07:25:31 +0200,
Cen Zhang wrote:
>
> 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,
Hmm, it's not clear how this happens. It looks like a typical
obscuration by AI reports...
Basically dummy_hrtimer_sync_stop should handled the hrtimer cancel,
but maybe the problem is rather its lack at releasing? If so, the
patch below should cover instead.
thanks,
Takashi
-- 8< --
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2301,6 +2301,8 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
result = snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
/* runtime->control->appl_ptr = runtime->status->hw_ptr; */
+ snd_pcm_sync_stop(substream, true);
+
return result;
}
next prev parent reply other threads:[~2026-10-14 7:19 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-14 5:25 [PATCH] ALSA: dummy: Defer hrtimer data freeing until runtime detach Cen Zhang
2026-10-14 7:19 ` Takashi Iwai [this message]
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=877bjkg35f.wl-tiwai@suse.de \
--to=tiwai@suse.de \
--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 \
--cc=zzzccc427@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.