From 53946579916b541adcf4986b1d9d87b2843e5095 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 2 Sep 2019 18:00:26 +0200 Subject: [PATCH] 4.9-stable patches added patches: alsa-usb-audio-fix-a-stack-buffer-overflow-bug-in-check_input_term.patch alsa-usb-audio-fix-an-oob-bug-in-parse_audio_mixer_unit.patch --- ...fer-overflow-bug-in-check_input_term.patch | 104 ++++++++++++++++++ ...an-oob-bug-in-parse_audio_mixer_unit.patch | 52 +++++++++ queue-4.9/series | 2 + 3 files changed, 158 insertions(+) create mode 100644 queue-4.9/alsa-usb-audio-fix-a-stack-buffer-overflow-bug-in-check_input_term.patch create mode 100644 queue-4.9/alsa-usb-audio-fix-an-oob-bug-in-parse_audio_mixer_unit.patch diff --git a/queue-4.9/alsa-usb-audio-fix-a-stack-buffer-overflow-bug-in-check_input_term.patch b/queue-4.9/alsa-usb-audio-fix-a-stack-buffer-overflow-bug-in-check_input_term.patch new file mode 100644 index 00000000000..6e7721e39a5 --- /dev/null +++ b/queue-4.9/alsa-usb-audio-fix-a-stack-buffer-overflow-bug-in-check_input_term.patch @@ -0,0 +1,104 @@ +From 19bce474c45be69a284ecee660aa12d8f1e88f18 Mon Sep 17 00:00:00 2001 +From: Hui Peng +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 + +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 +Reported-by: Mathias Payer +Signed-off-by: Hui Peng +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + + +--- + sound/usb/mixer.c | 29 ++++++++++++++++++++++++----- + 1 file changed, 24 insertions(+), 5 deletions(-) + +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -82,6 +82,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; +@@ -710,15 +711,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: +@@ -733,7 +743,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; + +@@ -765,7 +775,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 */ +@@ -812,6 +822,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 + */ diff --git a/queue-4.9/alsa-usb-audio-fix-an-oob-bug-in-parse_audio_mixer_unit.patch b/queue-4.9/alsa-usb-audio-fix-an-oob-bug-in-parse_audio_mixer_unit.patch new file mode 100644 index 00000000000..da8576fa307 --- /dev/null +++ b/queue-4.9/alsa-usb-audio-fix-an-oob-bug-in-parse_audio_mixer_unit.patch @@ -0,0 +1,52 @@ +From daac07156b330b18eb5071aec4b3ddca1c377f2c Mon Sep 17 00:00:00 2001 +From: Hui Peng +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 + +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 +Reported-by: Mathias Payer +Cc: +Signed-off-by: Hui Peng +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/usb/mixer.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -1713,6 +1713,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", diff --git a/queue-4.9/series b/queue-4.9/series index 9d299a091f9..5ccd9e2029e 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -53,3 +53,5 @@ tools-hv-fix-kvp-and-vss-daemons-exit-code.patch watchdog-bcm2835_wdt-fix-module-autoload.patch scsi-ufs-fix-rx_termination_force_enable-define-valu.patch tcp-fix-tcp_rtx_queue_tail-in-case-of-empty-retransm.patch +alsa-usb-audio-fix-a-stack-buffer-overflow-bug-in-check_input_term.patch +alsa-usb-audio-fix-an-oob-bug-in-parse_audio_mixer_unit.patch -- 2.47.3