[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <d4f3e70e-bbaa-6517-a2f2-8cd5e14c67cf@gmail.com>
Date: Thu, 15 Aug 2019 00:47:19 -0400
From: Hui Peng <benquike@...il.com>
To: security@...nel.org
Cc: mathias.payer@...elwelt.net, perex@...ex.cz, tiwai@...e.com,
tglx@...utronix.de, wang6495@....edu, allison@...utok.net,
yuehaibing@...wei.com, alsa-devel@...a-project.org,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH] Fix a stack buffer overflow bug check_input_term
The stack trace differs from test to test, the attached trace1 file is
taken from one of the tests.
The bug is confirmed by adding some printk statement in
`check_input_term`, the trace with output of printk is attached in
trace2 file.
This patch is a tentative fix to the bug, please give me feedback.
On 8/15/19 12:35 AM, Hui Peng wrote:
> `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;
View attachment "trace2" of type "text/plain" (13307 bytes)
View attachment "trace1" of type "text/plain" (5764 bytes)
Powered by blists - more mailing lists