Skip to content

Commit b560d67

Browse files
tiwaigregkh
authored andcommitted
ALSA: pcm: Fix races among concurrent prealloc proc writes
commit 69534c4 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent a38440f commit b560d67

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
@@ -164,19 +164,20 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
164164
size_t size;
165165
struct snd_dma_buffer new_dmab;
166166

167+
mutex_lock(&substream->pcm->open_mutex);
167168
if (substream->runtime) {
168169
buffer->error = -EBUSY;
169-
return;
170+
goto unlock;
170171
}
171172
if (!snd_info_get_line(buffer, line, sizeof(line))) {
172173
snd_info_get_str(str, line, sizeof(str));
173174
size = simple_strtoul(str, NULL, 10) * 1024;
174175
if ((size != 0 && size < 8192) || size > substream->dma_max) {
175176
buffer->error = -EINVAL;
176-
return;
177+
goto unlock;
177178
}
178179
if (substream->dma_buffer.bytes == size)
179-
return;
180+
goto unlock;
180181
memset(&new_dmab, 0, sizeof(new_dmab));
181182
new_dmab.dev = substream->dma_buffer.dev;
182183
if (size > 0) {
@@ -185,7 +186,7 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
185186
substream->dma_buffer.dev.dev,
186187
size, &new_dmab) < 0) {
187188
buffer->error = -ENOMEM;
188-
return;
189+
goto unlock;
189190
}
190191
substream->buffer_bytes_max = size;
191192
} else {
@@ -197,6 +198,8 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
197198
} else {
198199
buffer->error = -EINVAL;
199200
}
201+
unlock:
202+
mutex_unlock(&substream->pcm->open_mutex);
200203
}
201204

202205
static inline void preallocate_info_init(struct snd_pcm_substream *substream)

0 commit comments

Comments
 (0)