ALSA: usb-audio: Avoid access before bLength check in build_audio_procunit()
authorTakashi Iwai <tiwai@suse.de>
Wed, 19 Dec 2018 11:36:27 +0000 (12:36 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 13 Jan 2019 09:03:52 +0000 (10:03 +0100)
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.

Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
sound/usb/mixer.c

index db8404e31fae558f34dc60bd7dc60b02bbcb51af..64b90b8ec661ac57cf4f3c2bad4a8ca1f7557a14 100644 (file)
@@ -1882,7 +1882,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;
@@ -1897,7 +1897,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;