From b2500b584cfd228d67e1e43daf27c8af865b499e Mon Sep 17 00:00:00 2001 From: Julian Scheel Date: Thu, 16 Nov 2017 17:35:17 +0100 Subject: ALSA: usb-audio: uac1: Invalidate ctl on interrupt When an interrupt occurs, the value of at least one of the belonging controls should have changed. To make sure they get re-read from device on the next read, invalidate the cache. This was correctly implemented for uac2 already, but missing for uac1. Signed-off-by: Julian Scheel Signed-off-by: Takashi Iwai --- sound/usb/mixer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'sound/usb') diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 91bc8f18791e..1beb5b4d027e 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -2330,9 +2330,14 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid) { struct usb_mixer_elem_list *list; - for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) + for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) { + struct usb_mixer_elem_info *info = + (struct usb_mixer_elem_info *)list; + /* invalidate cache, so the value is read from the device */ + info->cached = 0; snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &list->kctl->id); + } } static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer, -- cgit From d937cd6790a2bef2d07b500487646bd794c039bb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 21 Nov 2017 16:55:51 +0100 Subject: ALSA: usb-audio: Add sanity checks to FE parser When the usb-audio descriptor contains the malformed feature unit description with a too short length, the driver may access out-of-bounds. Add a sanity check of the header size at the beginning of parse_audio_feature_unit(). Fixes: 23caaf19b11e ("ALSA: usb-mixer: Add support for Audio Class v2.0") Reported-by: Andrey Konovalov Cc: Signed-off-by: Takashi Iwai --- sound/usb/mixer.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'sound/usb') diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 1beb5b4d027e..b8ce651e392c 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1469,6 +1469,12 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, __u8 *bmaControls; if (state->mixer->protocol == UAC_VERSION_1) { + if (hdr->bLength < 7) { + usb_audio_err(state->chip, + "unit %u: invalid UAC_FEATURE_UNIT descriptor\n", + unitid); + return -EINVAL; + } csize = hdr->bControlSize; if (!csize) { usb_audio_dbg(state->chip, @@ -1486,6 +1492,12 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, } } else { struct uac2_feature_unit_descriptor *ftr = _ftr; + if (hdr->bLength < 6) { + usb_audio_err(state->chip, + "unit %u: invalid UAC_FEATURE_UNIT descriptor\n", + unitid); + return -EINVAL; + } csize = 4; channels = (hdr->bLength - 6) / 4 - 1; bmaControls = ftr->bmaControls; -- cgit From f658f17b5e0e339935dca23e77e0f3cad591926b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 21 Nov 2017 17:00:32 +0100 Subject: ALSA: usb-audio: Fix potential out-of-bound access at parsing SU The usb-audio driver may trigger an out-of-bound access at parsing a malformed selector unit, as it checks the header length only after evaluating bNrInPins field, which can be already above the given length. Fix it by adding the length check beforehand. Fixes: 99fc86450c43 ("ALSA: usb-mixer: parse descriptors with structs") Cc: Signed-off-by: Takashi Iwai --- sound/usb/mixer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound/usb') diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index b8ce651e392c..61b348383de8 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -2098,7 +2098,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, const struct usbmix_name_map *map; char **namelist; - if (!desc->bNrInPins || desc->bLength < 5 + desc->bNrInPins) { + if (desc->bLength < 5 || !desc->bNrInPins || + desc->bLength < 5 + desc->bNrInPins) { usb_audio_err(state->chip, "invalid SELECTOR UNIT descriptor %d\n", unitid); return -EINVAL; -- cgit From 8428a8ebde2db1e988e41a58497a28beb7ce1705 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 21 Nov 2017 17:07:43 +0100 Subject: ALSA: usb-audio: Fix potential zero-division at parsing FU parse_audio_feature_unit() contains a code dividing potentially with zero when a malformed FU descriptor is passed. Although there is already a sanity check, it checks only the value zero, hence it can still lead to a zero-division when a value 1 is passed there. Fix it by correcting the sanity check (and the error message thereof). Fixes: 23caaf19b11e ("ALSA: usb-mixer: Add support for Audio Class v2.0") Cc: Signed-off-by: Takashi Iwai --- sound/usb/mixer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/usb') diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 61b348383de8..0537c6322990 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1476,9 +1476,9 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, return -EINVAL; } csize = hdr->bControlSize; - if (!csize) { + if (csize <= 1) { usb_audio_dbg(state->chip, - "unit %u: invalid bControlSize == 0\n", + "unit %u: invalid bControlSize <= 1\n", unitid); return -EINVAL; } -- cgit From 0a62d6c966956d77397c32836a5bbfe3af786fc1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 21 Nov 2017 17:28:06 +0100 Subject: ALSA: usb-audio: Add sanity checks in v2 clock parsers The helper functions to parse and look for the clock source, selector and multiplier unit may return the descriptor with a too short length than required, while there is no sanity check in the caller side. Add some sanity checks in the parsers, at least, to guarantee the given descriptor size, for avoiding the potential crashes. Fixes: 79f920fbff56 ("ALSA: usb-audio: parse clock topology of UAC2 devices") Reported-by: Andrey Konovalov Cc: Signed-off-by: Takashi Iwai --- sound/usb/clock.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'sound/usb') diff --git a/sound/usb/clock.c b/sound/usb/clock.c index 26dd5f20f149..eb3396ffba4c 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c @@ -43,7 +43,7 @@ static struct uac_clock_source_descriptor * while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, ctrl_iface->extralen, cs, UAC2_CLOCK_SOURCE))) { - if (cs->bClockID == clock_id) + if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id) return cs; } @@ -59,8 +59,11 @@ static struct uac_clock_selector_descriptor * while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, ctrl_iface->extralen, cs, UAC2_CLOCK_SELECTOR))) { - if (cs->bClockID == clock_id) + if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id) { + if (cs->bLength < 5 + cs->bNrInPins) + return NULL; return cs; + } } return NULL; @@ -75,7 +78,7 @@ static struct uac_clock_multiplier_descriptor * while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, ctrl_iface->extralen, cs, UAC2_CLOCK_MULTIPLIER))) { - if (cs->bClockID == clock_id) + if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id) return cs; } -- cgit