Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: pcm: oss: Fix potential out-of-bounds shift

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+df7dc146ebdd6435eea3@syzkaller.appspotmail.com
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20201209084552.17109-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

+5 -1
+5 -1
sound/core/oss/pcm_oss.c
··· 1935 1935 static int snd_pcm_oss_set_fragment1(struct snd_pcm_substream *substream, unsigned int val) 1936 1936 { 1937 1937 struct snd_pcm_runtime *runtime; 1938 + int fragshift; 1938 1939 1939 1940 runtime = substream->runtime; 1940 1941 if (runtime->oss.subdivision || runtime->oss.fragshift) 1941 1942 return -EINVAL; 1942 - runtime->oss.fragshift = val & 0xffff; 1943 + fragshift = val & 0xffff; 1944 + if (fragshift >= 31) 1945 + return -EINVAL; 1946 + runtime->oss.fragshift = fragshift; 1943 1947 runtime->oss.maxfrags = (val >> 16) & 0xffff; 1944 1948 if (runtime->oss.fragshift < 4) /* < 16 */ 1945 1949 runtime->oss.fragshift = 4;