mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] ALSA: pcm: keep linked runtime alive while draining
@ 2026-06-05  5:16 Guangshuo Li
  2026-06-05  6:24 ` Takashi Iwai
  0 siblings, 1 reply; 3+ messages in thread
From: Guangshuo Li @ 2026-06-05  5:16 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai, Christophe Leroy, Mehul Rao,
	Nathan Chancellor, Cássio Gabriel, Guangshuo Li, Cen Zhang,
	Sebastian Andrzej Siewior, linux-sound, linux-kernel

snd_pcm_drain() may select a runtime from a linked playback stream and
queue a stack wait entry on its embedded sleep waitqueue. The function
then drops the stream lock and sleeps before removing the wait entry.

commit 9b1dbd69ba6f ("ALSA: pcm: fix use-after-free on linked stream
runtime in snd_pcm_drain()") cached scalar fields from the linked
runtime before dropping the stream lock, because a concurrent close can
unlink the stream and free its runtime. The same lifetime issue remains
for runtime->sleep. If the linked runtime is detached while the wait
entry is queued, remove_wait_queue() can later operate on a freed or
reused waitqueue, or the stack wait entry can remain linked to freed
memory.

Take snd_pcm_link_rwsem for read while the wait entry is queued on the
linked runtime. Acquire it before re-taking the stream lock, matching the
link/unlink lock order, and drop it only after the wait entry has been
removed.

Fixes: 21cb2a2ec581 ("[ALSA] Fix races between PCM drain and other ops")
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
 sound/core/pcm_native.c | 36 +++++++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 9 deletions(-)

diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index a541bb235cfa..1f7aba988e45 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2175,6 +2175,22 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
 			result = -ERESTARTSYS;
 			break;
 		}
+
+		/*
+		 * The wait below is queued on to_check->sleep, which is embedded
+		 * in a runtime that may belong to a linked substream.  Link/unlink
+		 * paths take snd_pcm_link_rwsem for write before moving streams
+		 * between groups and detaching runtimes, so take it for read while
+		 * the wait entry is queued.
+		 *
+		 * Drop and re-take the stream lock so the lock order matches
+		 * snd_pcm_link() and snd_pcm_unlink(): link_rwsem first, then the
+		 * stream/group lock.
+		 */
+		snd_pcm_stream_unlock_irq(substream);
+		down_read(&snd_pcm_link_rwsem);
+		snd_pcm_stream_lock_irq(substream);
+
 		/* find a substream to drain */
 		to_check = NULL;
 		group = snd_pcm_stream_group_ref(substream);
@@ -2188,8 +2204,14 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
 			}
 		}
 		snd_pcm_group_unref(group, substream);
-		if (!to_check)
+
+		if (!to_check) {
+			snd_pcm_stream_unlock_irq(substream);
+			up_read(&snd_pcm_link_rwsem);
+			snd_pcm_stream_lock_irq(substream);
 			break; /* all drained */
+		}
+
 		/*
 		 * Cache the runtime fields needed after unlock.
 		 * A concurrent close() on the linked stream may free
@@ -2216,14 +2238,10 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
 		tout = schedule_timeout(tout);
 
 		snd_pcm_stream_lock_irq(substream);
-		group = snd_pcm_stream_group_ref(substream);
-		snd_pcm_group_for_each_entry(s, substream) {
-			if (s->runtime == to_check) {
-				remove_wait_queue(&to_check->sleep, &wait);
-				break;
-			}
-		}
-		snd_pcm_group_unref(group, substream);
+		remove_wait_queue(&to_check->sleep, &wait);
+		snd_pcm_stream_unlock_irq(substream);
+		up_read(&snd_pcm_link_rwsem);
+		snd_pcm_stream_lock_irq(substream);
 
 		if (card->shutdown) {
 			result = -ENODEV;
-- 
2.43.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] ALSA: pcm: keep linked runtime alive while draining
  2026-06-05  5:16 [PATCH] ALSA: pcm: keep linked runtime alive while draining Guangshuo Li
@ 2026-06-05  6:24 ` Takashi Iwai
  2026-06-09 15:23   ` Guangshuo Li
  0 siblings, 1 reply; 3+ messages in thread
From: Takashi Iwai @ 2026-06-05  6:24 UTC (permalink / raw)
  To: Guangshuo Li
  Cc: Jaroslav Kysela, Takashi Iwai, Christophe Leroy, Mehul Rao,
	Nathan Chancellor, Cássio Gabriel, Cen Zhang,
	Sebastian Andrzej Siewior, linux-sound, linux-kernel

On Fri, 05 Jun 2026 07:16:37 +0200,
Guangshuo Li wrote:
> 
> snd_pcm_drain() may select a runtime from a linked playback stream and
> queue a stack wait entry on its embedded sleep waitqueue. The function
> then drops the stream lock and sleeps before removing the wait entry.
> 
> commit 9b1dbd69ba6f ("ALSA: pcm: fix use-after-free on linked stream
> runtime in snd_pcm_drain()") cached scalar fields from the linked
> runtime before dropping the stream lock, because a concurrent close can
> unlink the stream and free its runtime. The same lifetime issue remains
> for runtime->sleep. If the linked runtime is detached while the wait
> entry is queued, remove_wait_queue() can later operate on a freed or
> reused waitqueue, or the stack wait entry can remain linked to freed
> memory.
> 
> Take snd_pcm_link_rwsem for read while the wait entry is queued on the
> linked runtime. Acquire it before re-taking the stream lock, matching the
> link/unlink lock order, and drop it only after the wait entry has been
> removed.
> 
> Fixes: 21cb2a2ec581 ("[ALSA] Fix races between PCM drain and other ops")
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>

This should have been already fixed by the commit 88fe2e365872
  ALSA: PCM: Fix wait queue list corruption in snd_pcm_drain() on
  linked streams
in for-linus branch of sound.git tree.
Please check whether the issue still occurs.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] ALSA: pcm: keep linked runtime alive while draining
  2026-06-05  6:24 ` Takashi Iwai
@ 2026-06-09 15:23   ` Guangshuo Li
  0 siblings, 0 replies; 3+ messages in thread
From: Guangshuo Li @ 2026-06-09 15:23 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Jaroslav Kysela, Takashi Iwai, Christophe Leroy, Mehul Rao,
	Nathan Chancellor, Cássio Gabriel, Cen Zhang,
	Sebastian Andrzej Siewior, linux-sound, linux-kernel

Hi Takashi,

Thanks for the review and the pointer.

On Fri, 5 Jun 2026 at 14:24, Takashi Iwai <tiwai@suse.de> wrote:
>
> On Fri, 05 Jun 2026 07:16:37 +0200,
> Guangshuo Li wrote:
> >
> > snd_pcm_drain() may select a runtime from a linked playback stream and
> > queue a stack wait entry on its embedded sleep waitqueue. The function
> > then drops the stream lock and sleeps before removing the wait entry.
> >
> > commit 9b1dbd69ba6f ("ALSA: pcm: fix use-after-free on linked stream
> > runtime in snd_pcm_drain()") cached scalar fields from the linked
> > runtime before dropping the stream lock, because a concurrent close can
> > unlink the stream and free its runtime. The same lifetime issue remains
> > for runtime->sleep. If the linked runtime is detached while the wait
> > entry is queued, remove_wait_queue() can later operate on a freed or
> > reused waitqueue, or the stack wait entry can remain linked to freed
> > memory.
> >
> > Take snd_pcm_link_rwsem for read while the wait entry is queued on the
> > linked runtime. Acquire it before re-taking the stream lock, matching the
> > link/unlink lock order, and drop it only after the wait entry has been
> > removed.
> >
> > Fixes: 21cb2a2ec581 ("[ALSA] Fix races between PCM drain and other ops")
> > Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
>
> This should have been already fixed by the commit 88fe2e365872
>   ALSA: PCM: Fix wait queue list corruption in snd_pcm_drain() on
>   linked streams
> in for-linus branch of sound.git tree.
> Please check whether the issue still occurs.
>
>
> thanks,
>
> Takashi

I missed commit 88fe2e365872 ("ALSA: PCM: Fix wait queue list corruption
in snd_pcm_drain() on linked streams") in the sound.git for-linus branch.
After checking it, it addresses the waitqueue corruption case I was
looking at.

Thanks,
Guangshuo

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-06-09 15:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-05  5:16 [PATCH] ALSA: pcm: keep linked runtime alive while draining Guangshuo Li
2026-06-05  6:24 ` Takashi Iwai
2026-06-09 15:23   ` Guangshuo Li

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®