[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190815043554.16623-1-benquike@gmail.com>
Date: Thu, 15 Aug 2019 00:35:49 -0400
From: Hui Peng <benquike@...il.com>
To: security@...nel.org
Cc: Hui Peng <benquike@...il.com>,
Mathias Payer <mathias.payer@...elwelt.net>,
Jaroslav Kysela <perex@...ex.cz>,
Takashi Iwai <tiwai@...e.com>,
Thomas Gleixner <tglx@...utronix.de>,
Wenwen Wang <wang6495@....edu>,
Allison Randal <allison@...utok.net>,
YueHaibing <yuehaibing@...wei.com>, alsa-devel@...a-project.org,
linux-kernel@...r.kernel.org
Subject: [PATCH] Fix a stack buffer overflow bug check_input_term
`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 by `check_input_term` and stop
the execution if some id has been checked (similar to how
parse_audio_unit handles unitid argument).
Reported-by: Hui Peng <benquike@...il.com>
Reported-by: Mathias Payer <mathias.payer@...elwelt.net>
Signed-off-by: Hui Peng <benquike@...il.com>
---
sound/usb/mixer.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index ea487378be17..1f6c8213df82 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -68,6 +68,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;
@@ -782,6 +783,8 @@ static int check_input_term(struct mixer_build *state, int id,
int err;
void *p1;
+ if (test_and_set_bit(id, state->termbitmap))
+ return 0;
memset(term, 0, sizeof(*term));
while ((p1 = find_audio_control_unit(state, id)) != NULL) {
unsigned char *hdr = p1;
--
2.22.1
Powered by blists - more mailing lists