From: Takashi Iwai <ti...@suse.de>

commit 175b8d89fe292796811fdee87fa39799a5b6b87a upstream.

syzbot spotted a potential out-of-bounds shift in the PCM OSS layer
where it calculates the buffer size with the arbitrary shift value
given via an ioctl.

Add a range check for avoiding the undefined behavior.
As the value can be treated by a signed integer, the max shift should
be 30.

Reported-by: syzbot+df7dc146ebdd6435e...@syzkaller.appspotmail.com
Cc: <sta...@vger.kernel.org>
Link: https://lore.kernel.org/r/20201209084552.17109-2-ti...@suse.de
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 sound/core/oss/pcm_oss.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -2001,11 +2001,15 @@ static int snd_pcm_oss_set_subdivide(str
 static int snd_pcm_oss_set_fragment1(struct snd_pcm_substream *substream, 
unsigned int val)
 {
        struct snd_pcm_runtime *runtime;
+       int fragshift;
 
        runtime = substream->runtime;
        if (runtime->oss.subdivision || runtime->oss.fragshift)
                return -EINVAL;
-       runtime->oss.fragshift = val & 0xffff;
+       fragshift = val & 0xffff;
+       if (fragshift >= 31)
+               return -EINVAL;
+       runtime->oss.fragshift = fragshift;
        runtime->oss.maxfrags = (val >> 16) & 0xffff;
        if (runtime->oss.fragshift < 4)         /* < 16 */
                runtime->oss.fragshift = 4;


Reply via email to