ALSA: usb-audio: Fix potential out-of-bounce access in MIDI EP parser
authorTakashi Iwai <tiwai@suse.de>
Tue, 11 May 2021 09:05:00 +0000 (11:05 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 11 May 2021 09:10:37 +0000 (11:10 +0200)
The recently introduced MIDI endpoint parser code has an access to the
field without the size validation, hence it might lead to
out-of-bounce access.  Add the sanity checks for the descriptor
sizes.

Fixes: eb596e0fd13c ("ALSA: usb-audio: generate midi streaming substream names from jack names")
Link: https://lore.kernel.org/r/20210511090500.2637-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/midi.c

index 649eb8d..2c01649 100644 (file)
@@ -1750,7 +1750,7 @@ static struct usb_midi_in_jack_descriptor *find_usb_in_jack_descriptor(
                struct usb_midi_in_jack_descriptor *injd =
                                (struct usb_midi_in_jack_descriptor *)extra;
 
-               if (injd->bLength > 4 &&
+               if (injd->bLength >= sizeof(*injd) &&
                    injd->bDescriptorType == USB_DT_CS_INTERFACE &&
                    injd->bDescriptorSubtype == UAC_MIDI_IN_JACK &&
                                injd->bJackID == jack_id)
@@ -1773,7 +1773,7 @@ static struct usb_midi_out_jack_descriptor *find_usb_out_jack_descriptor(
                struct usb_midi_out_jack_descriptor *outjd =
                                (struct usb_midi_out_jack_descriptor *)extra;
 
-               if (outjd->bLength > 4 &&
+               if (outjd->bLength >= sizeof(*outjd) &&
                    outjd->bDescriptorType == USB_DT_CS_INTERFACE &&
                    outjd->bDescriptorSubtype == UAC_MIDI_OUT_JACK &&
                                outjd->bJackID == jack_id)
@@ -1820,7 +1820,8 @@ static void snd_usbmidi_init_substream(struct snd_usb_midi *umidi,
                        outjd = find_usb_out_jack_descriptor(hostif, jack_id);
                        if (outjd) {
                                sz = USB_DT_MIDI_OUT_SIZE(outjd->bNrInputPins);
-                               iJack = *(((uint8_t *) outjd) + sz - sizeof(uint8_t));
+                               if (outjd->bLength >= sz)
+                                       iJack = *(((uint8_t *) outjd) + sz - sizeof(uint8_t));
                        }
                } else {
                        /* and out jacks connect to ins */