From: Karl Mehltretter <kmehltretter@gmail.com>
To: stable@vger.kernel.org
Cc: "Karl Mehltretter" <kmehltretter@gmail.com>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Jaroslav Kysela" <perex@perex.cz>,
"Takashi Iwai" <tiwai@suse.com>,
"Cássio Gabriel" <cassiogabrielcontato@gmail.com>,
linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org,
syzbot+5f8f3acdee1ec7a7ef7b@syzkaller.appspotmail.com,
"Takashi Iwai" <tiwai@suse.de>
Subject: [PATCH 6.1.y 1/2] ALSA: aloop: Fix racy access at PCM trigger
Date: Tue, 1 Sep 2026 11:13:01 +0200 [thread overview]
Message-ID: <20260901091302.66860-2-kmehltretter@gmail.com> (raw)
In-Reply-To: <20260901091302.66860-1-kmehltretter@gmail.com>
From: Takashi Iwai <tiwai@suse.de>
[ Upstream commit 826af7fa62e347464b1b4e0ba2fe19a92438084f ]
The PCM trigger callback of aloop driver tries to check the PCM state
and stop the stream of the tied substream in the corresponding cable.
Since both check and stop operations are performed outside the cable
lock, this may result in UAF when a program attempts to trigger
frequently while opening/closing the tied stream, as spotted by
fuzzers.
For addressing the UAF, this patch changes two things:
- It covers the most of code in loopback_check_format() with
cable->lock spinlock, and add the proper NULL checks. This avoids
already some racy accesses.
- In addition, now we try to check the state of the capture PCM stream
that may be stopped in this function, which was the major pain point
leading to UAF.
Reported-by: syzbot+5f8f3acdee1ec7a7ef7b@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/69783ba1.050a0220.c9109.0011.GAE@google.com
Cc: <stable@vger.kernel.org>
Link: https://patch.msgid.link/20260203141003.116584-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
[ Karl Mehltretter: dropped the access-mode comparison and notification
(462494565c27, e299a9fd433f, cdac6e1f7164). ]
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
sound/drivers/aloop.c | 58 +++++++++++++++++++++++++------------------
1 file changed, 34 insertions(+), 24 deletions(-)
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index a38e602b4fc60..67bbadcec02b0 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -319,35 +319,41 @@ static int loopback_snd_timer_close_cable(struct loopback_pcm *dpcm)
static int loopback_check_format(struct loopback_cable *cable, int stream)
{
+ struct loopback_pcm *dpcm_play, *dpcm_capt;
struct snd_pcm_runtime *runtime, *cruntime;
struct loopback_setup *setup;
struct snd_card *card;
+ bool stop_capture = false;
int check;
- if (cable->valid != CABLE_VALID_BOTH) {
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- goto __notify;
- return 0;
- }
- runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
- substream->runtime;
- cruntime = cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
- substream->runtime;
- check = runtime->format != cruntime->format ||
- runtime->rate != cruntime->rate ||
- runtime->channels != cruntime->channels;
- if (!check)
- return 0;
- if (stream == SNDRV_PCM_STREAM_CAPTURE) {
- return -EIO;
- } else {
- snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
- substream, SNDRV_PCM_STATE_DRAINING);
- __notify:
- runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
- substream->runtime;
- setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]);
- card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card;
+ scoped_guard(spinlock_irqsave, &cable->lock) {
+ dpcm_play = cable->streams[SNDRV_PCM_STREAM_PLAYBACK];
+ dpcm_capt = cable->streams[SNDRV_PCM_STREAM_CAPTURE];
+
+ if (cable->valid != CABLE_VALID_BOTH) {
+ if (stream == SNDRV_PCM_STREAM_CAPTURE || !dpcm_play)
+ return 0;
+ } else {
+ if (!dpcm_play || !dpcm_capt)
+ return -EIO;
+ runtime = dpcm_play->substream->runtime;
+ cruntime = dpcm_capt->substream->runtime;
+ if (!runtime || !cruntime)
+ return -EIO;
+ check = runtime->format != cruntime->format ||
+ runtime->rate != cruntime->rate ||
+ runtime->channels != cruntime->channels;
+ if (!check)
+ return 0;
+ if (stream == SNDRV_PCM_STREAM_CAPTURE)
+ return -EIO;
+ else if (cruntime->state == SNDRV_PCM_STATE_RUNNING)
+ stop_capture = true;
+ }
+
+ setup = get_setup(dpcm_play);
+ card = dpcm_play->loopback->card;
+ runtime = dpcm_play->substream->runtime;
if (setup->format != runtime->format) {
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&setup->format_id);
@@ -364,6 +370,10 @@ static int loopback_check_format(struct loopback_cable *cable, int stream)
setup->channels = runtime->channels;
}
}
+
+ if (stop_capture)
+ snd_pcm_stop(dpcm_capt->substream, SNDRV_PCM_STATE_DRAINING);
+
return 0;
}
--
2.53.0
next prev parent reply other threads:[~2026-09-01 9:13 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <2026050445-connector-rebuff-f713@gregkh>
2026-09-01 9:13 ` [PATCH 6.1.y 0/2] ALSA: aloop: fix trigger/close UAFs Karl Mehltretter
2026-09-01 9:13 ` Karl Mehltretter [this message]
2026-09-01 9:13 ` [PATCH 6.1.y 2/2] ALSA: aloop: Fix peer runtime UAF during format-change stop Karl Mehltretter
2026-09-02 22:14 ` [PATCH 6.1.y 0/2] ALSA: aloop: fix trigger/close UAFs Sasha Levin
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=20260901091302.66860-2-kmehltretter@gmail.com \
--to=kmehltretter@gmail.com \
--cc=cassiogabrielcontato@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=perex@perex.cz \
--cc=stable@vger.kernel.org \
--cc=syzbot+5f8f3acdee1ec7a7ef7b@syzkaller.appspotmail.com \
--cc=tiwai@suse.com \
--cc=tiwai@suse.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox