blob: 905accdc2c0f8c985f3bce540bda7006d20ececb [file] [log] [blame]
From 72fc265279b0ff9584ab6d47e8fc2ba2ce444cf6 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Fri, 24 Apr 2020 21:33:50 +0200
Subject: [PATCH] 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: Paul Gortmaker <paul.gortmaker@windriver.com>
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
--
2.7.4