summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2020-04-24 21:33:50 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-05-06 08:15:08 +0200
commitea63e38b29e7417ce5e20914fd617e5e19e03680 (patch)
tree5fd31bd0ff425eab3cdbd2d0c9b30611b0801cab
parentc867614f196ae8acf5e644e1e1f1e18e280cb33b (diff)
downloadlinux-stable-ea63e38b29e7417ce5e20914fd617e5e19e03680.tar.gz
linux-stable-ea63e38b29e7417ce5e20914fd617e5e19e03680.tar.bz2
linux-stable-ea63e38b29e7417ce5e20914fd617e5e19e03680.zip
ALSA: pcm: oss: Place the plugin buffer overflow checks correctly
commit 4285de0725b1bf73608abbcd35ad7fd3ddc0b61e upstream. The checks of the plugin buffer overflow in the previous fix by commit f2ecf903ef06 ("ALSA: pcm: oss: Avoid plugin buffer overflow") are put in the wrong places mistakenly, which leads to the expected (repeated) sound when the rate plugin is involved. Fix in the right places. Also, at those right places, the zero check is needed for the termination node, so added there as well, and let's get it done, finally. Fixes: f2ecf903ef06 ("ALSA: pcm: oss: Avoid plugin buffer overflow") Cc: <stable@vger.kernel.org> Link: https://lore.kernel.org/r/20200424193350.19678-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--sound/core/oss/pcm_plugin.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
index 8539047145de..da400da1fafe 100644
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -211,21 +211,23 @@ static snd_pcm_sframes_t plug_client_size(struct snd_pcm_substream *plug,
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
plugin = snd_pcm_plug_last(plug);
while (plugin && drv_frames > 0) {
- if (check_size && drv_frames > plugin->buf_frames)
- drv_frames = plugin->buf_frames;
plugin_prev = plugin->prev;
if (plugin->src_frames)
drv_frames = plugin->src_frames(plugin, drv_frames);
+ if (check_size && plugin->buf_frames &&
+ drv_frames > plugin->buf_frames)
+ drv_frames = plugin->buf_frames;
plugin = plugin_prev;
}
} else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
plugin = snd_pcm_plug_first(plug);
while (plugin && drv_frames > 0) {
plugin_next = plugin->next;
+ if (check_size && plugin->buf_frames &&
+ drv_frames > plugin->buf_frames)
+ drv_frames = plugin->buf_frames;
if (plugin->dst_frames)
drv_frames = plugin->dst_frames(plugin, drv_frames);
- if (check_size && drv_frames > plugin->buf_frames)
- drv_frames = plugin->buf_frames;
plugin = plugin_next;
}
} else
@@ -251,26 +253,28 @@ static snd_pcm_sframes_t plug_slave_size(struct snd_pcm_substream *plug,
plugin = snd_pcm_plug_first(plug);
while (plugin && frames > 0) {
plugin_next = plugin->next;
+ if (check_size && plugin->buf_frames &&
+ frames > plugin->buf_frames)
+ frames = plugin->buf_frames;
if (plugin->dst_frames) {
frames = plugin->dst_frames(plugin, frames);
if (frames < 0)
return frames;
}
- if (check_size && frames > plugin->buf_frames)
- frames = plugin->buf_frames;
plugin = plugin_next;
}
} else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
plugin = snd_pcm_plug_last(plug);
while (plugin) {
- if (check_size && frames > plugin->buf_frames)
- frames = plugin->buf_frames;
plugin_prev = plugin->prev;
if (plugin->src_frames) {
frames = plugin->src_frames(plugin, frames);
if (frames < 0)
return frames;
}
+ if (check_size && plugin->buf_frames &&
+ frames > plugin->buf_frames)
+ frames = plugin->buf_frames;
plugin = plugin_prev;
}
} else