diff options
author | Takashi Iwai <tiwai@suse.de> | 2018-12-19 14:36:27 +0300 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2019-05-02 23:41:10 +0300 |
commit | cacb39e5e4b7de790939b174165503bbe8c82208 (patch) | |
tree | 785cf91896bf84cdb70403c96899dae9d0163963 /sound/usb | |
parent | b1c840e32de6ee663645dcb76e43e06de51bd598 (diff) | |
download | linux-cacb39e5e4b7de790939b174165503bbe8c82208.tar.xz |
ALSA: usb-audio: Avoid access before bLength check in build_audio_procunit()
commit f4351a199cc120ff9d59e06d02e8657d08e6cc46 upstream.
The parser for the processing unit reads bNrInPins field before the
bLength sanity check, which may lead to an out-of-bound access when a
malformed descriptor is given. Fix it by assignment after the bLength
check.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/mixer.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index caf392f2aea0..538df481fe5e 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1787,7 +1787,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, char *name) { struct uac_processing_unit_descriptor *desc = raw_desc; - int num_ins = desc->bNrInPins; + int num_ins; struct usb_mixer_elem_info *cval; struct snd_kcontrol *kctl; int i, err, nameid, type, len; @@ -1802,7 +1802,13 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, 0, NULL, default_value_info }; - if (desc->bLength < 13 || desc->bLength < 13 + num_ins || + if (desc->bLength < 13) { + usb_audio_err(state->chip, "invalid %s descriptor (id %d)\n", name, unitid); + return -EINVAL; + } + + num_ins = desc->bNrInPins; + if (desc->bLength < 13 + num_ins || desc->bLength < num_ins + uac_processing_unit_bControlSize(desc, state->mixer->protocol)) { usb_audio_err(state->chip, "invalid %s descriptor (id %d)\n", name, unitid); return -EINVAL; |