if (state->mixer->protocol == UAC_VERSION_2) {
                struct uac2_input_terminal_descriptor *d_v2 = raw_desc;
+               if (d_v2->bLength < sizeof(*d_v2))
+                       return -EINVAL;
                control = UAC2_TE_CONNECTOR;
                term_id = d_v2->bTerminalID;
                bmctls = le16_to_cpu(d_v2->bmControls);
        } else if (state->mixer->protocol == UAC_VERSION_3) {
                struct uac3_input_terminal_descriptor *d_v3 = raw_desc;
+               if (d_v3->bLength < sizeof(*d_v3))
+                       return -EINVAL;
                control = UAC3_TE_INSERTION;
                term_id = d_v3->bTerminalID;
                bmctls = le32_to_cpu(d_v3->bmControls);
 
                csep = snd_usb_find_desc(alts->extra, alts->extralen, NULL, USB_DT_CS_ENDPOINT);
 
        if (!csep || csep->bLength < 7 ||
-           csep->bDescriptorSubtype != UAC_EP_GENERAL) {
-               usb_audio_warn(chip,
-                              "%u:%d : no or invalid class specific endpoint descriptor\n",
-                              iface_no, altsd->bAlternateSetting);
-               return 0;
-       }
+           csep->bDescriptorSubtype != UAC_EP_GENERAL)
+               goto error;
 
        if (protocol == UAC_VERSION_1) {
                attributes = csep->bmAttributes;
                struct uac2_iso_endpoint_descriptor *csep2 =
                        (struct uac2_iso_endpoint_descriptor *) csep;
 
+               if (csep2->bLength < sizeof(*csep2))
+                       goto error;
                attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX;
 
                /* emulate the endpoint attributes of a v1 device */
                struct uac3_iso_endpoint_descriptor *csep3 =
                        (struct uac3_iso_endpoint_descriptor *) csep;
 
+               if (csep3->bLength < sizeof(*csep3))
+                       goto error;
                /* emulate the endpoint attributes of a v1 device */
                if (le32_to_cpu(csep3->bmControls) & UAC2_CONTROL_PITCH)
                        attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL;
        }
 
        return attributes;
+
+ error:
+       usb_audio_warn(chip,
+                      "%u:%d : no or invalid class specific endpoint descriptor\n",
+                      iface_no, altsd->bAlternateSetting);
+       return 0;
 }
 
 /* find an input terminal descriptor (either UAC1 or UAC2) with the given
  */
 static void *
 snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface,
-                                              int terminal_id)
+                                      int terminal_id, bool uac23)
 {
        struct uac2_input_terminal_descriptor *term = NULL;
+       size_t minlen = uac23 ? sizeof(struct uac2_input_terminal_descriptor) :
+               sizeof(struct uac_input_terminal_descriptor);
 
        while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
                                               ctrl_iface->extralen,
                                               term, UAC_INPUT_TERMINAL))) {
+               if (term->bLength < minlen)
+                       continue;
                if (term->bTerminalID == terminal_id)
                        return term;
        }
        while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
                                               ctrl_iface->extralen,
                                               term, UAC_OUTPUT_TERMINAL))) {
-               if (term->bTerminalID == terminal_id)
+               if (term->bLength >= sizeof(*term) &&
+                   term->bTerminalID == terminal_id)
                        return term;
        }
 
                format = le16_to_cpu(as->wFormatTag); /* remember the format value */
 
                iterm = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
-                                                            as->bTerminalLink);
+                                                              as->bTerminalLink,
+                                                              false);
                if (iterm) {
                        num_channels = iterm->bNrChannels;
                        chconfig = le16_to_cpu(iterm->wChannelConfig);
                 * to extract the clock
                 */
                input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
-                                                                   as->bTerminalLink);
+                                                                   as->bTerminalLink,
+                                                                   true);
                if (input_term) {
                        clock = input_term->bCSourceID;
                        if (!chconfig && (num_channels == input_term->bNrChannels))
         * to extract the clock
         */
        input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
-                                                           as->bTerminalLink);
+                                                           as->bTerminalLink,
+                                                           true);
        if (input_term) {
                clock = input_term->bCSourceID;
                goto found_clock;