From nobody Mon Jun 8 07:24:55 2026 Received: from mail-pj1-f46.google.com (mail-pj1-f46.google.com [209.85.216.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 96591353EC0 for ; Fri, 5 Jun 2026 05:16:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780636618; cv=none; b=ZfBv4+w5p0V5H8wOvV6Wj+jptGLu/fHakQxJkV/DeWZl+u/QvTSg/RXPEDCcaLAoSaaxI/LNSdxXHe3Gn/gkBpxM6YrNQYZmQCeZxhi7hmTEJUuHNO2nluo+bXzI4H3EQD+B8Gntdm6ThlqrSRGFK1JTvRROGtYSHfLTd0IYb7E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780636618; c=relaxed/simple; bh=9f+jaBTiw0YCCwjO8rY5tpPp9Jp2rSXjEWVZ3tmfie0=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=Z+1QzpkvgeyyILOT+t4+T6Lm/KmfgFUtQv38x28XqXr3+2gZ5kIsz1J4i5kyhy5zrWypYrB3QsuqbzGIE5Dh3/leuy4B/A5MiJlCJndIqN6OOTIrVhLuU2j8G9BN9KIxUU4blFuIaIOeM9HDAHYrvYxNj7uhfp4N6IBg28SOCUg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=C0O0CcGR; arc=none smtp.client-ip=209.85.216.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="C0O0CcGR" Received: by mail-pj1-f46.google.com with SMTP id 98e67ed59e1d1-36b8d414666so946189a91.3 for ; Thu, 04 Jun 2026 22:16:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780636616; x=1781241416; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=pD9CqhmzX6JNf1uZuVqTL+AJSUpqeYSBphcg8pxVa58=; b=C0O0CcGRtv96nSEFL62BzsFNPyq8VrkNYVe8XjR6Au97Bl3NuC5NjWwDbia8ojapoW S6u8AAgnd5HiZFWPW4zt9eI4/GIBoQBcMH4doQNTsI5/s5F4AccwoMdzXbdMpJJfejNT Ms/Hr08REFrXzFvDszbppIvrVsbyAAx83Bm6cVXMkR5sPlWdWDgG/Gj2k1MmEQOz/nwe B4jW+ImpyYZrGPK2iKfCHNcL0mt/ioNI4Ul1r0vdqGJKAhL/uEqxyNVIb8M+cFrxLx1p +aMLMf4FVYLkPUulcVYnmB15uWX/wonKjno7UB6BuNnVaT/xWIqmneGNjLsNk42BKtbc FTjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780636616; x=1781241416; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=pD9CqhmzX6JNf1uZuVqTL+AJSUpqeYSBphcg8pxVa58=; b=ctR8mgYZXLQFe7cTqEx/lq5gc4vdjPcWz19XD59Ncje+0vzvcmZkTUHdXnQVGlFRN+ S/q4E1uCbzA3pXQdy78z6w/QYgS7sbJ1ZlYo7JvIsZEvCJwvjQvky7/4f9ehPxAeypuB FJH07ZIpagvJE2HojuoqOxCTn3I/8I1sZbEL/Rkr5RTX/Ex1EQd/MB3kGXUCXxAIbzXG 7oVw2+Z+3R3/5pKsnO3+ny4rfQ0ho9xftklVQw2AoiAa6WfJjTS7Xx/TpMbGEJo6jWBJ ef0Pr/fgaEBtBoNn1Xh/rOtEuiiq7TNQuNRJQKU7wzT9e7YrxhSPizsNYP8uzeq0f9IV dIoA== X-Forwarded-Encrypted: i=1; AFNElJ/oYAevFbMQy6c9AwZEDSl/M/BiJ6oMku+sxF8HadcALMTDLaw2XuBu8li7Ff77C3LxmkYHyBCE3+xZOXc=@vger.kernel.org X-Gm-Message-State: AOJu0Yyi+V6a4FD01iAEqfmtCQqzfjM7E8CaAL8npsuYsBZ/waAH56gY GuhJwsxCpp1brWFdj4Ux4//EjKq1b5WvNMNWMiBT+Lk8RBm1VthNSBS4 X-Gm-Gg: Acq92OGZGB7j2oBfst6C4IrMafm+k6n4b2bPwva/uqtEc6Cn6uEdtbcqk/Wft9jXCBv u4w8RnrJM4nrHbL/9XKhJjk9MSEvjPFlPz1mhaFgfKLHSsyiQAHmAFj9wu2zJftQy3z5zKZWx9E dNdbFNJL4czTLvu7zzzhufSTJMweVnmLb6it9od0AJ5+SmlFKyIS5K5G2Ys6D6n0UNGSA69nLHL nSgozTrt8NCPBV5/ytjC/sR3P5XD4fl2dgUNDW3Xk99aoZ1OlO08bB9WVnknwhfQbKZXOAKZHSo BQEkwrS2FTEJZoN25UR3Lg+zZZN6coLzaHuT83kv/AlNzntS5zXlTC8/AZ5xXXDsFJ4AJIXiqpw E+e+1oo8hteX0KByGsrTbuuhEQn5Xb1k8w2j7+aFhBKi4kMetz3kOv2/6o31jZGvqgYiJC6iV1l BhzLseXW95KQOMyBDY0FXoGedL X-Received: by 2002:a17:90b:53c6:b0:369:a359:b181 with SMTP id 98e67ed59e1d1-370f162420amr2107012a91.23.1780636615786; Thu, 04 Jun 2026 22:16:55 -0700 (PDT) Received: from lgs.. ([101.36.107.181]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c85df0b2ddbsm6514164a12.24.2026.06.04.22.16.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jun 2026 22:16:55 -0700 (PDT) From: Guangshuo Li To: Jaroslav Kysela , Takashi Iwai , Christophe Leroy , Mehul Rao , Nathan Chancellor , =?UTF-8?q?C=C3=A1ssio=20Gabriel?= , Guangshuo Li , Cen Zhang , Sebastian Andrzej Siewior , linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] ALSA: pcm: keep linked runtime alive while draining Date: Fri, 5 Jun 2026 13:16:37 +0800 Message-ID: <20260605051637.1442529-1-lgs201920130244@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- 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 *s= ubstream, result =3D -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 =3D NULL; group =3D snd_pcm_stream_group_ref(substream); @@ -2188,8 +2204,14 @@ static int snd_pcm_drain(struct snd_pcm_substream *s= ubstream, } } 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 =3D schedule_timeout(tout); =20 snd_pcm_stream_lock_irq(substream); - group =3D snd_pcm_stream_group_ref(substream); - snd_pcm_group_for_each_entry(s, substream) { - if (s->runtime =3D=3D 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); =20 if (card->shutdown) { result =3D -ENODEV; --=20 2.43.0