From: Cássio Gabriel Date: Fri, 27 Mar 2026 13:59:45 +0000 (-0300) Subject: ALSA: pcm: Serialize snd_pcm_suspend_all() with open_mutex X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1a56641b7ae4f19216774a59d68024be3e6197d0;p=thirdparty%2Flinux.git ALSA: pcm: Serialize snd_pcm_suspend_all() with open_mutex snd_pcm_suspend_all() walks all PCM substreams and uses a lockless runtime check to skip closed streams. It then calls snd_pcm_suspend() for each remaining substream and finally runs snd_pcm_sync_stop() in a second pass. The runtime lifetime is still controlled by pcm->open_mutex in the open/release path. That means a concurrent close can clear or free substream->runtime after the initial check in snd_pcm_suspend_all(), leaving the later suspend or sync-stop path to dereference a stale or NULL runtime pointer. Serialize snd_pcm_suspend_all() with pcm->open_mutex so the runtime pointer stays stable across both loops. This matches the existing PCM runtime lifetime rule already used by other core paths that access substream->runtime outside the stream lock. Suggested-by: Takashi Iwai Signed-off-by: Cássio Gabriel Link: https://patch.msgid.link/20260327-alsa-pcm-suspend-open-close-lock-v2-1-cc4baca4dcd6@gmail.com Signed-off-by: Takashi Iwai --- diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 394f86bc4d29..aefb861ab873 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1780,6 +1780,9 @@ static int snd_pcm_suspend(struct snd_pcm_substream *substream) * snd_pcm_suspend_all - trigger SUSPEND to all substreams in the given pcm * @pcm: the PCM instance * + * Takes and releases pcm->open_mutex to serialize against + * concurrent open/close while walking the substreams. + * * After this call, all streams are changed to SUSPENDED state. * * Return: Zero if successful (or @pcm is %NULL), or a negative error code. @@ -1792,8 +1795,9 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm) if (! pcm) return 0; + guard(mutex)(&pcm->open_mutex); + for_each_pcm_substream(pcm, stream, substream) { - /* FIXME: the open/close code should lock this as well */ if (!substream->runtime) continue;