Skip to content

Commit f2ecf90

Browse files
committed
ALSA: pcm: oss: Avoid plugin buffer overflow
Each OSS PCM plugins allocate its internal buffer per pre-calculation of the max buffer size through the chain of plugins (calling src_frames and dst_frames callbacks). This works for most plugins, but the rate plugin might behave incorrectly. The calculation in the rate plugin involves with the fractional position, i.e. it may vary depending on the input position. Since the buffer size pre-calculation is always done with the offset zero, it may return a shorter size than it might be; this may result in the out-of-bound access as spotted by fuzzer. This patch addresses those possible buffer overflow accesses by simply setting the upper limit per the given buffer size for each plugin before src_frames() and after dst_frames() calls. Reported-by: [email protected] Cc: <[email protected]> Link: https://lore.kernel.org/r/[email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 5a56996 commit f2ecf90

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

sound/core/oss/pcm_plugin.c

+8
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_p
209209
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
210210
plugin = snd_pcm_plug_last(plug);
211211
while (plugin && drv_frames > 0) {
212+
if (drv_frames > plugin->buf_frames)
213+
drv_frames = plugin->buf_frames;
212214
plugin_prev = plugin->prev;
213215
if (plugin->src_frames)
214216
drv_frames = plugin->src_frames(plugin, drv_frames);
@@ -220,6 +222,8 @@ snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_p
220222
plugin_next = plugin->next;
221223
if (plugin->dst_frames)
222224
drv_frames = plugin->dst_frames(plugin, drv_frames);
225+
if (drv_frames > plugin->buf_frames)
226+
drv_frames = plugin->buf_frames;
223227
plugin = plugin_next;
224228
}
225229
} else
@@ -248,11 +252,15 @@ snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug, snd_pc
248252
if (frames < 0)
249253
return frames;
250254
}
255+
if (frames > plugin->buf_frames)
256+
frames = plugin->buf_frames;
251257
plugin = plugin_next;
252258
}
253259
} else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
254260
plugin = snd_pcm_plug_last(plug);
255261
while (plugin) {
262+
if (frames > plugin->buf_frames)
263+
frames = plugin->buf_frames;
256264
plugin_prev = plugin->prev;
257265
if (plugin->src_frames) {
258266
frames = plugin->src_frames(plugin, frames);

0 commit comments

Comments
 (0)