[PATCH 1/2] ALSA: usb-audio: Fix potential out-of-bounds shift
syzbot spotted a potential out-of-bounds shift in the USB-audio format parser that receives the arbitrary shift value from the USB descriptor.
Add a range check for avoiding the undefined behavior.
Reported-by: syzbot+df7dc146ebdd6435eea3@syzkaller.appspotmail.com Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/usb/format.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/usb/format.c b/sound/usb/format.c index 93459ba228d3..9ebc5d202c87 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -39,6 +39,8 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip, case UAC_VERSION_1: default: { struct uac_format_type_i_discrete_descriptor *fmt = _fmt; + if (format >= 64) + return 0; /* invalid format */ sample_width = fmt->bBitResolution; sample_bytes = fmt->bSubframeSize; format = 1ULL << format;
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 Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/core/oss/pcm_oss.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 327ec42a36b0..de1917484647 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -1935,11 +1935,15 @@ static int snd_pcm_oss_set_subdivide(struct snd_pcm_oss_file *pcm_oss_file, int 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;
participants (1)
-
Takashi Iwai