public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ALSA: pcm: fix use-after-free on linked stream runtime in snd_pcm_drain()
@ 2026-03-05 19:35 Mehul Rao
  2026-03-09  8:57 ` Takashi Iwai
  0 siblings, 1 reply; 3+ messages in thread
From: Mehul Rao @ 2026-03-05 19:35 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai
  Cc: linux-sound, linux-kernel, stable, Mehul Rao

In the drain loop, the local variable 'runtime' is reassigned to a
linked stream's runtime (runtime = s->runtime at line 2157).  After
releasing the stream lock at line 2169, the code accesses
runtime->no_period_wakeup, runtime->rate, and runtime->buffer_size
(lines 2170-2178) — all referencing the linked stream's runtime without
any lock or refcount protecting its lifetime.

A concurrent close() on the linked stream's fd triggers
snd_pcm_release_substream() → snd_pcm_drop() → pcm_release_private()
→ snd_pcm_unlink() → snd_pcm_detach_substream() → kfree(runtime).
No synchronization prevents kfree(runtime) from completing while the
drain path dereferences the stale pointer.

Fix by caching the needed runtime fields (no_period_wakeup, rate,
buffer_size) into local variables while still holding the stream lock,
and using the cached values after the lock is released.

Fixes: f2b3614cefb6 ("ALSA: PCM - Don't check DMA time-out too shortly")
Cc: stable@vger.kernel.org
Signed-off-by: Mehul Rao <mehulrao@gmail.com>
---
 sound/core/pcm_native.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 67cf6a0e1..5a64453da 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -2144,6 +2144,10 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
 	for (;;) {
 		long tout;
 		struct snd_pcm_runtime *to_check;
+		unsigned int drain_rate;
+		snd_pcm_uframes_t drain_bufsz;
+		bool drain_no_period_wakeup;
+
 		if (signal_pending(current)) {
 			result = -ERESTARTSYS;
 			break;
@@ -2163,16 +2167,25 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
 		snd_pcm_group_unref(group, substream);
 		if (!to_check)
 			break; /* all drained */
+		/*
+		 * Cache the runtime fields needed after unlock.
+		 * A concurrent close() on the linked stream may free
+		 * its runtime via snd_pcm_detach_substream() once we
+		 * release the stream lock below.
+		 */
+		drain_no_period_wakeup = to_check->no_period_wakeup;
+		drain_rate = to_check->rate;
+		drain_bufsz = to_check->buffer_size;
 		init_waitqueue_entry(&wait, current);
 		set_current_state(TASK_INTERRUPTIBLE);
 		add_wait_queue(&to_check->sleep, &wait);
 		snd_pcm_stream_unlock_irq(substream);
-		if (runtime->no_period_wakeup)
+		if (drain_no_period_wakeup)
 			tout = MAX_SCHEDULE_TIMEOUT;
 		else {
 			tout = 100;
-			if (runtime->rate) {
-				long t = runtime->buffer_size * 1100 / runtime->rate;
+			if (drain_rate) {
+				long t = drain_bufsz * 1100 / drain_rate;
 				tout = max(t, tout);
 			}
 			tout = msecs_to_jiffies(tout);
--
2.48.1

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

* Re: [PATCH] ALSA: pcm: fix use-after-free on linked stream runtime in snd_pcm_drain()
  2026-03-05 19:35 [PATCH] ALSA: pcm: fix use-after-free on linked stream runtime in snd_pcm_drain() Mehul Rao
@ 2026-03-09  8:57 ` Takashi Iwai
       [not found]   ` <CAMNhdctTJYdzQvv1MtZtqUjYSjrtiu_6J6E9eQJSjx-wmXfWKg@mail.gmail.com>
  0 siblings, 1 reply; 3+ messages in thread
From: Takashi Iwai @ 2026-03-09  8:57 UTC (permalink / raw)
  To: Mehul Rao
  Cc: Jaroslav Kysela, Takashi Iwai, linux-sound, linux-kernel, stable

On Thu, 05 Mar 2026 20:35:07 +0100,
Mehul Rao wrote:
> 
> In the drain loop, the local variable 'runtime' is reassigned to a
> linked stream's runtime (runtime = s->runtime at line 2157).  After
> releasing the stream lock at line 2169, the code accesses
> runtime->no_period_wakeup, runtime->rate, and runtime->buffer_size
> (lines 2170-2178) ― all referencing the linked stream's runtime without
> any lock or refcount protecting its lifetime.
> 
> A concurrent close() on the linked stream's fd triggers
> snd_pcm_release_substream() → snd_pcm_drop() → pcm_release_private()
> → snd_pcm_unlink() → snd_pcm_detach_substream() → kfree(runtime).
> No synchronization prevents kfree(runtime) from completing while the
> drain path dereferences the stale pointer.
> 
> Fix by caching the needed runtime fields (no_period_wakeup, rate,
> buffer_size) into local variables while still holding the stream lock,
> and using the cached values after the lock is released.
> 
> Fixes: f2b3614cefb6 ("ALSA: PCM - Don't check DMA time-out too shortly")
> Cc: stable@vger.kernel.org
> Signed-off-by: Mehul Rao <mehulrao@gmail.com>

Do you have the actual crash by fuzzer or such?  Or is it only
theoretical?

In anyway, I applied now as the fix looks fine and safe.


thanks,

Takashi

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

* Re: [PATCH] ALSA: pcm: fix use-after-free on linked stream runtime in snd_pcm_drain()
       [not found]   ` <CAMNhdctTJYdzQvv1MtZtqUjYSjrtiu_6J6E9eQJSjx-wmXfWKg@mail.gmail.com>
@ 2026-03-10 17:25     ` Takashi Iwai
  0 siblings, 0 replies; 3+ messages in thread
From: Takashi Iwai @ 2026-03-10 17:25 UTC (permalink / raw)
  To: Mehul Rao
  Cc: Takashi Iwai, Jaroslav Kysela, Takashi Iwai, linux-sound,
	linux-kernel, stable

On Tue, 10 Mar 2026 18:11:19 +0100,
Mehul Rao wrote:
> 
> 
> Hi Takashi,  
> 
> Thanks for applying!
> 
> It was found through an LLM-assisted static analysis pipeline that scans
> kernel subsystems for concurrency bugs, then verified with KASAN by writing a
> PoC that races snd_pcm_drain() against snd_pcm_close() on linked snd-dummy
> substreams from two threads.
> 
> The race window is narrow, so I injected a msleep(50) between the unlock and
> the runtime field access to reliably trigger the KASAN splat
> (slab-use-after-free in snd_pcm_drain). Without the delay it didn't fire in
> 3000 iterations though.
> 
> Please let me know if you would like these kinds of patches in the future. I
> am new to kernel development and this was one of my first patches. I am trying
> to learn as I go.

Sure, more fixes in this level of good quality are appreciated.


thanks,

Takashi

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

end of thread, other threads:[~2026-03-10 17:25 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-05 19:35 [PATCH] ALSA: pcm: fix use-after-free on linked stream runtime in snd_pcm_drain() Mehul Rao
2026-03-09  8:57 ` Takashi Iwai
     [not found]   ` <CAMNhdctTJYdzQvv1MtZtqUjYSjrtiu_6J6E9eQJSjx-wmXfWKg@mail.gmail.com>
2026-03-10 17:25     ` Takashi Iwai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox