Skip to content

Commit 69534c4

Browse files
committed
ALSA: pcm: Fix races among concurrent prealloc proc writes
We have no protection against concurrent PCM buffer preallocation changes via proc files, and it may potentially lead to UAF or some weird problem. This patch applies the PCM open_mutex to the proc write operation for avoiding the racy proc writes and the PCM stream open (and further operations). Cc: <stable@vger.kernel.org> Reviewed-by: Jaroslav Kysela <perex@perex.cz> Link: https://lore.kernel.org/r/20220322170720.3529-5-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 3c3201f commit 69534c4

1 file changed

Lines changed: 7 additions & 4 deletions

File tree

sound/core/pcm_memory.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,19 +163,20 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
163163
size_t size;
164164
struct snd_dma_buffer new_dmab;
165165

166+
mutex_lock(&substream->pcm->open_mutex);
166167
if (substream->runtime) {
167168
buffer->error = -EBUSY;
168-
return;
169+
goto unlock;
169170
}
170171
if (!snd_info_get_line(buffer, line, sizeof(line))) {
171172
snd_info_get_str(str, line, sizeof(str));
172173
size = simple_strtoul(str, NULL, 10) * 1024;
173174
if ((size != 0 && size < 8192) || size > substream->dma_max) {
174175
buffer->error = -EINVAL;
175-
return;
176+
goto unlock;
176177
}
177178
if (substream->dma_buffer.bytes == size)
178-
return;
179+
goto unlock;
179180
memset(&new_dmab, 0, sizeof(new_dmab));
180181
new_dmab.dev = substream->dma_buffer.dev;
181182
if (size > 0) {
@@ -189,7 +190,7 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
189190
substream->pcm->card->number, substream->pcm->device,
190191
substream->stream ? 'c' : 'p', substream->number,
191192
substream->pcm->name, size);
192-
return;
193+
goto unlock;
193194
}
194195
substream->buffer_bytes_max = size;
195196
} else {
@@ -201,6 +202,8 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
201202
} else {
202203
buffer->error = -EINVAL;
203204
}
205+
unlock:
206+
mutex_unlock(&substream->pcm->open_mutex);
204207
}
205208

206209
static inline void preallocate_info_init(struct snd_pcm_substream *substream)

0 commit comments

Comments
 (0)