summaryrefslogtreecommitdiff
path: root/sound/usb/mixer.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-08-20 18:17:09 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-11-12 21:20:48 +0300
commit17821e2fb16752f5d363fb5c3f8aab4df41b9bcc (patch)
tree9651161eda539472f4f109aff8d4fb17c8adac17 /sound/usb/mixer.c
parent5e36cf8edb5812e378b57511263d1a0a9172eeb9 (diff)
downloadlinux-17821e2fb16752f5d363fb5c3f8aab4df41b9bcc.tar.xz
ALSA: usb-audio: More validations of descriptor units
commit 57f8770620e9b51c61089751f0b5ad3dbe376ff2 upstream. Introduce a new helper to validate each audio descriptor unit before and check the unit before actually accessing it. This should harden against the OOB access cases with malformed descriptors that have been recently frequently reported by fuzzers. The existing descriptor checks are still kept although they become superfluous after this patch. They'll be cleaned up eventually later. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'sound/usb/mixer.c')
-rw-r--r--sound/usb/mixer.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index b0c5d4ef6137..78f2a94e0e6a 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -800,6 +800,8 @@ static int __check_input_term(struct mixer_build *state, int id,
p1 = find_audio_control_unit(state, id);
if (!p1)
break;
+ if (!snd_usb_validate_audio_desc(p1, protocol))
+ break; /* bad descriptor */
hdr = p1;
term->id = id;
@@ -2794,6 +2796,11 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
return -EINVAL;
}
+ if (!snd_usb_validate_audio_desc(p1, protocol)) {
+ usb_audio_dbg(state->chip, "invalid unit %d\n", unitid);
+ return 0; /* skip invalid unit */
+ }
+
if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) {
switch (p1[2]) {
case UAC_INPUT_TERMINAL:
@@ -3164,6 +3171,9 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
while ((p = snd_usb_find_csint_desc(mixer->hostif->extra,
mixer->hostif->extralen,
p, UAC_OUTPUT_TERMINAL)) != NULL) {
+ if (!snd_usb_validate_audio_desc(p, mixer->protocol))
+ continue; /* skip invalid descriptor */
+
if (mixer->protocol == UAC_VERSION_1) {
struct uac1_output_terminal_descriptor *desc = p;