ALSA: usb-audio: Fix out-of-bound error
[pandora-kernel.git] / sound / usb / mixer.c
index a489f2f..4e10164 100644 (file)
@@ -197,6 +197,10 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un
 static int snd_usb_copy_string_desc(struct mixer_build *state, int index, char *buf, int maxlen)
 {
        int len = usb_string(state->chip->dev, index, buf, maxlen - 1);
+
+       if (len < 0)
+               return 0;
+
        buf[len] = 0;
        return len;
 }
@@ -1255,6 +1259,12 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
        __u8 *bmaControls;
 
        if (state->mixer->protocol == UAC_VERSION_1) {
+               if (hdr->bLength < 7) {
+                       snd_printk(KERN_ERR
+                                  "usbaudio: unit %u: invalid UAC_FEATURE_UNIT descriptor\n",
+                                  unitid);
+                       return -EINVAL;
+               }
                csize = hdr->bControlSize;
                if (!csize) {
                        snd_printdd(KERN_ERR "usbaudio: unit %u: "
@@ -1271,6 +1281,12 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
                }
        } else {
                struct uac2_feature_unit_descriptor *ftr = _ftr;
+               if (hdr->bLength < 6) {
+                       snd_printk(KERN_ERR
+                                  "usbaudio: unit %u: invalid UAC_FEATURE_UNIT descriptor\n",
+                                  unitid);
+                       return -EINVAL;
+               }
                csize = 4;
                channels = (hdr->bLength - 6) / 4 - 1;
                bmaControls = ftr->bmaControls;
@@ -1833,7 +1849,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void
        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) {
                snd_printk(KERN_ERR "invalid SELECTOR UNIT descriptor %d\n", unitid);
                return -EINVAL;
        }