Skip to content

Commit 6b01c1b

Browse files
tiwaigregkh
authored andcommitted
ALSA: pcm: oss: Fix data race at accessing runtime.oss.trigger
commit 901ac0f upstream. Currently the runtime.oss.trigger field may be accessed concurrently without protection, which may lead to the data race. And, in this case, it may lead to more severe problem because it's a bit field; as writing the data, it may overwrite other bit fields as well, which confuses the operation completely, as spotted by fuzzing. Fix it by covering runtime.oss.trigger bit fled also with the existing params_lock mutex in both snd_pcm_oss_get_trigger() and snd_pcm_oss_poll(). Reported-and-tested-by: Jaeyoung Chung <jjy600901@snu.ac.kr> Closes: https://lore.kernel.org/20260423145330.210035-1-jjy600901@snu.ac.kr Cc: <stable@vger.kernel.org> Link: https://patch.msgid.link/20260424112205.123703-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent ea52465 commit 6b01c1b

1 file changed

Lines changed: 23 additions & 6 deletions

File tree

sound/core/oss/pcm_oss.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2149,10 +2149,16 @@ static int snd_pcm_oss_get_trigger(struct snd_pcm_oss_file *pcm_oss_file)
21492149

21502150
psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
21512151
csubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
2152-
if (psubstream && psubstream->runtime && psubstream->runtime->oss.trigger)
2153-
result |= PCM_ENABLE_OUTPUT;
2154-
if (csubstream && csubstream->runtime && csubstream->runtime->oss.trigger)
2155-
result |= PCM_ENABLE_INPUT;
2152+
if (psubstream && psubstream->runtime) {
2153+
guard(mutex)(&psubstream->runtime->oss.params_lock);
2154+
if (psubstream->runtime->oss.trigger)
2155+
result |= PCM_ENABLE_OUTPUT;
2156+
}
2157+
if (csubstream && csubstream->runtime) {
2158+
guard(mutex)(&csubstream->runtime->oss.params_lock);
2159+
if (csubstream->runtime->oss.trigger)
2160+
result |= PCM_ENABLE_INPUT;
2161+
}
21562162
return result;
21572163
}
21582164

@@ -2826,6 +2832,17 @@ static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream)
28262832
runtime->oss.period_frames;
28272833
}
28282834

2835+
static bool need_input_retrigger(struct snd_pcm_runtime *runtime)
2836+
{
2837+
bool ret;
2838+
2839+
guard(mutex)(&runtime->oss.params_lock);
2840+
ret = runtime->oss.trigger;
2841+
if (ret)
2842+
runtime->oss.trigger = 0;
2843+
return ret;
2844+
}
2845+
28292846
static __poll_t snd_pcm_oss_poll(struct file *file, poll_table * wait)
28302847
{
28312848
struct snd_pcm_oss_file *pcm_oss_file;
@@ -2858,11 +2875,11 @@ static __poll_t snd_pcm_oss_poll(struct file *file, poll_table * wait)
28582875
snd_pcm_oss_capture_ready(csubstream))
28592876
mask |= EPOLLIN | EPOLLRDNORM;
28602877
}
2861-
if (ostate != SNDRV_PCM_STATE_RUNNING && runtime->oss.trigger) {
2878+
if (ostate != SNDRV_PCM_STATE_RUNNING &&
2879+
need_input_retrigger(runtime)) {
28622880
struct snd_pcm_oss_file ofile;
28632881
memset(&ofile, 0, sizeof(ofile));
28642882
ofile.streams[SNDRV_PCM_STREAM_CAPTURE] = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
2865-
runtime->oss.trigger = 0;
28662883
snd_pcm_oss_set_trigger(&ofile, PCM_ENABLE_INPUT);
28672884
}
28682885
}

0 commit comments

Comments
 (0)