--- /dev/null
+From 19bce474c45be69a284ecee660aa12d8f1e88f18 Mon Sep 17 00:00:00 2001
+From: Hui Peng <benquike@gmail.com>
+Date: Thu, 15 Aug 2019 00:31:34 -0400
+Subject: ALSA: usb-audio: Fix a stack buffer overflow bug in check_input_term
+
+From: Hui Peng <benquike@gmail.com>
+
+commit 19bce474c45be69a284ecee660aa12d8f1e88f18 upstream.
+
+`check_input_term` recursively calls itself with input from
+device side (e.g., uac_input_terminal_descriptor.bCSourceID)
+as argument (id). In `check_input_term`, if `check_input_term`
+is called with the same `id` argument as the caller, it triggers
+endless recursive call, resulting kernel space stack overflow.
+
+This patch fixes the bug by adding a bitmap to `struct mixer_build`
+to keep track of the checked ids and stop the execution if some id
+has been checked (similar to how parse_audio_unit handles unitid
+argument).
+
+Reported-by: Hui Peng <benquike@gmail.com>
+Reported-by: Mathias Payer <mathias.payer@nebelwelt.net>
+Signed-off-by: Hui Peng <benquike@gmail.com>
+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 | 29 ++++++++++++++++++++++++-----
+ 1 file changed, 24 insertions(+), 5 deletions(-)
+
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -81,6 +81,7 @@ struct mixer_build {
+ unsigned char *buffer;
+ unsigned int buflen;
+ DECLARE_BITMAP(unitbitmap, MAX_ID_ELEMS);
++ DECLARE_BITMAP(termbitmap, MAX_ID_ELEMS);
+ struct usb_audio_term oterm;
+ const struct usbmix_name_map *map;
+ const struct usbmix_selector_map *selector_map;
+@@ -709,15 +710,24 @@ static int get_term_name(struct mixer_bu
+ * parse the source unit recursively until it reaches to a terminal
+ * or a branched unit.
+ */
+-static int check_input_term(struct mixer_build *state, int id,
++static int __check_input_term(struct mixer_build *state, int id,
+ struct usb_audio_term *term)
+ {
+ int err;
+ void *p1;
++ unsigned char *hdr;
+
+ memset(term, 0, sizeof(*term));
+- while ((p1 = find_audio_control_unit(state, id)) != NULL) {
+- unsigned char *hdr = p1;
++ for (;;) {
++ /* a loop in the terminal chain? */
++ if (test_and_set_bit(id, state->termbitmap))
++ return -EINVAL;
++
++ p1 = find_audio_control_unit(state, id);
++ if (!p1)
++ break;
++
++ hdr = p1;
+ term->id = id;
+ switch (hdr[2]) {
+ case UAC_INPUT_TERMINAL:
+@@ -732,7 +742,7 @@ static int check_input_term(struct mixer
+
+ /* call recursively to verify that the
+ * referenced clock entity is valid */
+- err = check_input_term(state, d->bCSourceID, term);
++ err = __check_input_term(state, d->bCSourceID, term);
+ if (err < 0)
+ return err;
+
+@@ -764,7 +774,7 @@ static int check_input_term(struct mixer
+ case UAC2_CLOCK_SELECTOR: {
+ struct uac_selector_unit_descriptor *d = p1;
+ /* call recursively to retrieve the channel info */
+- err = check_input_term(state, d->baSourceID[0], term);
++ err = __check_input_term(state, d->baSourceID[0], term);
+ if (err < 0)
+ return err;
+ term->type = d->bDescriptorSubtype << 16; /* virtual type */
+@@ -811,6 +821,15 @@ static int check_input_term(struct mixer
+ return -ENODEV;
+ }
+
++
++static int check_input_term(struct mixer_build *state, int id,
++ struct usb_audio_term *term)
++{
++ memset(term, 0, sizeof(*term));
++ memset(state->termbitmap, 0, sizeof(state->termbitmap));
++ return __check_input_term(state, id, term);
++}
++
+ /*
+ * Feature Unit
+ */
--- /dev/null
+From daac07156b330b18eb5071aec4b3ddca1c377f2c Mon Sep 17 00:00:00 2001
+From: Hui Peng <benquike@gmail.com>
+Date: Tue, 13 Aug 2019 22:34:04 -0400
+Subject: ALSA: usb-audio: Fix an OOB bug in parse_audio_mixer_unit
+
+From: Hui Peng <benquike@gmail.com>
+
+commit daac07156b330b18eb5071aec4b3ddca1c377f2c upstream.
+
+The `uac_mixer_unit_descriptor` shown as below is read from the
+device side. In `parse_audio_mixer_unit`, `baSourceID` field is
+accessed from index 0 to `bNrInPins` - 1, the current implementation
+assumes that descriptor is always valid (the length of descriptor
+is no shorter than 5 + `bNrInPins`). If a descriptor read from
+the device side is invalid, it may trigger out-of-bound memory
+access.
+
+```
+struct uac_mixer_unit_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bUnitID;
+ __u8 bNrInPins;
+ __u8 baSourceID[];
+}
+```
+
+This patch fixes the bug by add a sanity check on the length of
+the descriptor.
+
+Reported-by: Hui Peng <benquike@gmail.com>
+Reported-by: Mathias Payer <mathias.payer@nebelwelt.net>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Hui Peng <benquike@gmail.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/usb/mixer.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -1647,6 +1647,7 @@ static int parse_audio_mixer_unit(struct
+ int pin, ich, err;
+
+ if (desc->bLength < 11 || !(input_pins = desc->bNrInPins) ||
++ desc->bLength < sizeof(*desc) + desc->bNrInPins ||
+ !(num_outs = uac_mixer_unit_bNrChannels(desc))) {
+ usb_audio_err(state->chip,
+ "invalid MIXER UNIT descriptor %d\n",