linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Fix a stack buffer overflow bug check_input_term
@ 2019-08-15  4:35 Hui Peng
  2019-08-15  4:47 ` Hui Peng
  2019-08-15  6:13 ` Takashi Iwai
  0 siblings, 2 replies; 6+ messages in thread
From: Hui Peng @ 2019-08-15  4:35 UTC (permalink / raw)
  To: security
  Cc: Hui Peng, Mathias Payer, Jaroslav Kysela, Takashi Iwai,
	Thomas Gleixner, Wenwen Wang, Allison Randal, YueHaibing,
	alsa-devel, linux-kernel

`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@gmail.com>
Reported-by: Mathias Payer <mathias.payer@nebelwelt.net>
Signed-off-by: Hui Peng <benquike@gmail.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


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Fix a stack buffer overflow bug check_input_term
  2019-08-15  4:35 [PATCH] Fix a stack buffer overflow bug check_input_term Hui Peng
@ 2019-08-15  4:47 ` Hui Peng
  2019-08-15  6:13 ` Takashi Iwai
  1 sibling, 0 replies; 6+ messages in thread
From: Hui Peng @ 2019-08-15  4:47 UTC (permalink / raw)
  To: security
  Cc: mathias.payer, perex, tiwai, tglx, wang6495, allison, yuehaibing,
	alsa-devel, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1899 bytes --]

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@gmail.com>
> Reported-by: Mathias Payer <mathias.payer@nebelwelt.net>
> Signed-off-by: Hui Peng <benquike@gmail.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;

[-- Attachment #2: trace2 --]
[-- Type: text/plain, Size: 13307 bytes --]

[    7.839002] usb 1-1: new high-speed USB device number 2 using xhci_hcd
[    7.966787] usb 1-1: Using ep0 maxpacket: 16
[    7.969898] usb 1-1: string descriptor 0 read error: -22
[    7.971507] usb 1-1: New USB device found, idVendor=046d, idProduct=0a44, bcdDevice= 1.27
[    7.973874] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[    7.979864] usb 1-1: current rate 16732531 is different from the runtime rate 48000
[    7.982029] usb 1-1: current rate 11254477 is different from the runtime rate 48000
[    7.987190] [parse_audio_unit:2797] reached
[    7.987741] [parse_audio_unit:2814] reached
[    7.988310] [parse_audio_feature_unit:1855] reached
[    7.988982] [parse_audio_feature_unit:1915] reached
[    7.989605] [parse_audio_unit:2797] reached
[    7.990173] [parse_audio_unit:2804] reached
[    7.999615] [parse_audio_unit:2797] reached
[    8.000166] [parse_audio_unit:2814] reached
[    8.000734] [parse_audio_feature_unit:1855] reached
[    8.001361] [parse_audio_feature_unit:1915] reached
[    8.002011] [parse_audio_unit:2797] reached
[    8.002590] [parse_audio_unit:2811] reached
[    8.003180] [parse_audio_unit:2797] reached
[    8.003754] [parse_audio_unit:2814] reached
[    8.004342] [parse_audio_feature_unit:1855] reached
[    8.004992] [parse_audio_feature_unit:1915] reached
[    8.005656] [parse_audio_feature_unit:1921] reached
[    8.006324] [check_input_term:804] reached
[    8.006881] [check_input_term:860] reached
[    8.007451] [check_input_term:804] reached
[    8.008038] [check_input_term:860] reached
[    8.008596] [check_input_term:804] reached
[    8.009129] [check_input_term:860] reached
[    8.009686] [check_input_term:804] reached
[    8.010217] [check_input_term:860] reached
[    8.010834] [check_input_term:804] reached
[    8.011430] [check_input_term:860] reached
[    8.011945] [check_input_term:804] reached
[    8.012577] [check_input_term:860] reached
[    8.013109] [check_input_term:804] reached
[    8.013704] [check_input_term:860] reached
[    8.014319] [check_input_term:804] reached
[    8.014848] [check_input_term:860] reached
[    8.015415] [check_input_term:804] reached
[    8.015964] [check_input_term:860] reached
[    8.016525] [check_input_term:804] reached
[    8.017055] [check_input_term:860] reached
[    8.017612] [check_input_term:804] reached
[    8.018168] [check_input_term:860] reached
[    8.018701] [check_input_term:804] reached
[    8.019273] [check_input_term:860] reached
[    8.019805] [check_input_term:804] reached
[    8.020362] [check_input_term:860] reached
[    8.020893] [check_input_term:804] reached
[    8.021440] [check_input_term:860] reached
[    8.021972] [check_input_term:804] reached
[    8.022536] [check_input_term:860] reached
[    8.023127] [check_input_term:804] reached
[    8.023664] [check_input_term:860] reached
[    8.024213] [check_input_term:804] reached
[    8.024791] [check_input_term:860] reached
[    8.025351] [check_input_term:804] reached
[    8.025886] [check_input_term:860] reached
[    8.026435] [check_input_term:804] reached
[    8.026986] [check_input_term:860] reached
[    8.027509] [check_input_term:804] reached
[    8.028061] [check_input_term:860] reached
[    8.028596] [check_input_term:804] reached
[    8.029145] [check_input_term:860] reached
[    8.029690] [check_input_term:804] reached
[    8.030252] [check_input_term:860] reached
[    8.030786] [check_input_term:804] reached
[    8.031357] [check_input_term:860] reached
[    8.031922] [check_input_term:804] reached
[    8.032456] [check_input_term:860] reached
[    8.033018] [check_input_term:804] reached
[    8.033552] [check_input_term:860] reached
[    8.034115] [check_input_term:804] reached
[    8.034650] [check_input_term:860] reached
[    8.035210] [check_input_term:804] reached
[    8.035785] [check_input_term:860] reached
[    8.036318] [check_input_term:804] reached
[    8.036879] [check_input_term:860] reached
[    8.037414] [check_input_term:804] reached
[    8.037976] [check_input_term:860] reached
[    8.038511] [check_input_term:804] reached
[    8.039072] [check_input_term:860] reached
[    8.039652] [check_input_term:804] reached
[    8.040181] [check_input_term:860] reached
[    8.040738] [check_input_term:804] reached
[    8.041279] [check_input_term:860] reached
[    8.041840] [check_input_term:804] reached
[    8.042377] [check_input_term:860] reached
[    8.042940] [check_input_term:804] reached
[    8.043553] [check_input_term:860] reached
[    8.044084] [check_input_term:804] reached
[    8.044648] [check_input_term:860] reached
[    8.045188] [check_input_term:804] reached
[    8.045838] [check_input_term:860] reached
[    8.046375] [check_input_term:804] reached
[    8.046940] [check_input_term:860] reached
[    8.047517] [check_input_term:804] reached
[    8.048069] [check_input_term:860] reached
[    8.048671] [check_input_term:804] reached
[    8.049255] [check_input_term:860] reached
[    8.049818] [check_input_term:804] reached
[    8.050393] [check_input_term:860] reached
[    8.050938] [check_input_term:804] reached
[    8.051513] [check_input_term:860] reached
[    8.052049] [check_input_term:804] reached
[    8.052601] [check_input_term:860] reached
[    8.053117] [check_input_term:804] reached
[    8.053681] [check_input_term:860] reached
[    8.054218] [check_input_term:804] reached
[    8.054782] [check_input_term:860] reached
[    8.055355] [check_input_term:804] reached
[    8.055889] [check_input_term:860] reached
[    8.056451] [check_input_term:804] reached
[    8.056987] [check_input_term:860] reached
[    8.057552] [check_input_term:804] reached
[    8.058098] [check_input_term:860] reached
[    8.058658] [check_input_term:804] reached
[    8.059266] [check_input_term:860] reached
[    8.059800] [check_input_term:804] reached
[    8.060353] [check_input_term:860] reached
[    8.060995] [check_input_term:804] reached
[    8.061559] [check_input_term:860] reached
[    8.062126] [check_input_term:804] reached
[    8.062661] [check_input_term:860] reached
[    8.063224] [check_input_term:804] reached
[    8.063769] [check_input_term:860] reached
[    8.064335] [check_input_term:804] reached
[    8.064871] [check_input_term:860] reached
[    8.065425] [check_input_term:804] reached
[    8.065975] [check_input_term:860] reached
[    8.066524] [check_input_term:804] reached
[    8.067087] [check_input_term:860] reached
[    8.067630] [check_input_term:804] reached
[    8.068191] [check_input_term:860] reached
[    8.068728] [check_input_term:804] reached
[    8.069292] [check_input_term:860] reached
[    8.069827] [check_input_term:804] reached
[    8.070379] [check_input_term:860] reached
[    8.070931] [check_input_term:804] reached
[    8.071493] [check_input_term:860] reached
[    8.072055] [check_input_term:804] reached
[    8.072589] [check_input_term:860] reached
[    8.073155] [check_input_term:804] reached
[    8.073709] [check_input_term:860] reached
[    8.074338] [check_input_term:804] reached
[    8.074911] [check_input_term:860] reached
[    8.075482] [check_input_term:804] reached
[    8.076075] [check_input_term:860] reached
[    8.076610] [check_input_term:804] reached
[    8.077185] [check_input_term:860] reached
[    8.077751] [check_input_term:804] reached
[    8.078284] [check_input_term:860] reached
[    8.078846] [check_input_term:804] reached
[    8.079397] [check_input_term:860] reached
[    8.079987] [check_input_term:804] reached
[    8.080522] [check_input_term:860] reached
[    8.081084] [check_input_term:804] reached
[    8.081650] [check_input_term:860] reached
[    8.082225] [check_input_term:804] reached
[    8.082794] [check_input_term:860] reached
[    8.085551] [check_input_term:804] reached
[    8.086089] [check_input_term:860] reached
[    8.086653] [check_input_term:804] reached
[    8.087188] [check_input_term:860] reached
[    8.087760] [check_input_term:804] reached
[    8.088295] [check_input_term:860] reached
[    8.088855] [check_input_term:804] reached
[    8.089400] [check_input_term:860] reached
[    8.089990] [check_input_term:804] reached
[    8.090554] [check_input_term:860] reached
[    8.091089] [check_input_term:804] reached
[    8.091661] [check_input_term:860] reached
[    8.092193] [check_input_term:804] reached
[    8.092752] [check_input_term:860] reached
[    8.093369] [check_input_term:804] reached
[    8.093939] [check_input_term:860] reached
[    8.094488] [check_input_term:804] reached
[    8.095004] [check_input_term:860] reached
[    8.095574] [check_input_term:804] reached
[    8.096113] [check_input_term:860] reached
[    8.096675] [check_input_term:804] reached
[    8.097240] [check_input_term:860] reached
[    8.097805] [check_input_term:804] reached
[    8.098380] [check_input_term:860] reached
[    8.098919] [check_input_term:804] reached
[    8.099533] [check_input_term:860] reached
[    8.100121] [check_input_term:804] reached
[    8.100651] [check_input_term:860] reached
[    8.101229] [check_input_term:804] reached
[    8.101859] [check_input_term:860] reached
[    8.102515] [check_input_term:804] reached
[    8.103190] [check_input_term:860] reached
[    8.103806] [check_input_term:804] reached
[    8.104393] [check_input_term:860] reached
[    8.104921] [check_input_term:804] reached
[    8.105466] [check_input_term:860] reached
[    8.106065] [check_input_term:804] reached
[    8.106598] [check_input_term:860] reached
[    8.107160] [check_input_term:804] reached
[    8.107701] [check_input_term:860] reached
[    8.108269] [check_input_term:804] reached
[    8.108804] [check_input_term:860] reached
[    8.109364] [check_input_term:804] reached
[    8.109945] [check_input_term:860] reached
[    8.110480] [check_input_term:804] reached
[    8.111043] [check_input_term:860] reached
[    8.111612] [check_input_term:804] reached
[    8.112179] [check_input_term:860] reached
[    8.112715] [check_input_term:804] reached
[    8.113278] [check_input_term:860] reached
[    8.113848] [check_input_term:804] reached
[    8.114384] [check_input_term:860] reached
[    8.114943] [check_input_term:804] reached
[    8.115517] [check_input_term:860] reached
[    8.116080] [check_input_term:804] reached
[    8.116656] [check_input_term:860] reached
[    8.117219] [check_input_term:804] reached
[    8.117785] [check_input_term:860] reached
[    8.118379] [check_input_term:804] reached
[    8.118943] [check_input_term:860] reached
[    8.119485] [check_input_term:804] reached
[    8.120048] [check_input_term:860] reached
[    8.120613] [check_input_term:804] reached
[    8.121205] [check_input_term:860] reached
[    8.121767] [check_input_term:804] reached
[    8.122301] [check_input_term:860] reached
[    8.122867] [check_input_term:804] reached
[    8.123430] [check_input_term:860] reached
[    8.123995] [check_input_term:804] reached
[    8.124562] [check_input_term:860] reached
[    8.125093] [check_input_term:804] reached
[    8.125652] [check_input_term:860] reached
[    8.126253] [check_input_term:804] reached
[    8.126814] [check_input_term:860] reached
[    8.127350] [check_input_term:804] reached
[    8.127942] [check_input_term:860] reached
[    8.128506] [check_input_term:804] reached
[    8.129038] [check_input_term:860] reached
[    8.129594] [check_input_term:804] reached
[    8.130193] [check_input_term:860] reached
[    8.130756] [check_input_term:804] reached
[    8.131298] [check_input_term:860] reached
[    8.131855] [check_input_term:804] reached
[    8.132411] [check_input_term:860] reached
[    8.132969] [check_input_term:804] reached
[    8.133568] [check_input_term:860] reached
[    8.134103] [check_input_term:804] reached
[    8.134658] [check_input_term:860] reached
[    8.135251] [check_input_term:804] reached
[    8.135780] [check_input_term:860] reached
[    8.136345] [check_input_term:804] reached
[    8.136882] [check_input_term:860] reached
[    8.137446] [check_input_term:804] reached
[    8.137979] [check_input_term:860] reached
[    8.138547] [check_input_term:804] reached
[    8.139081] [check_input_term:860] reached
[    8.139642] [check_input_term:804] reached
[    8.140208] [check_input_term:860] reached
[    8.140741] [check_input_term:804] reached
[    8.141313] [check_input_term:860] reached
[    8.141848] [check_input_term:804] reached
[    8.142408] [check_input_term:860] reached
[    8.142957] [check_input_term:804] reached
[    8.143525] [check_input_term:860] reached
[    8.144088] [check_input_term:804] reached
[    8.144618] [check_input_term:860] reached
[    8.145179] [check_input_term:804] reached
[    8.145712] [check_input_term:860] reached
[    8.146298] [check_input_term:804] reached
[    8.146817] [check_input_term:860] reached
[    8.147416] [check_input_term:804] reached
[    8.147990] [check_input_term:860] reached
[    8.148522] [check_input_term:804] reached
[    8.149081] [check_input_term:860] reached
[    8.149624] [check_input_term:804] reached
[    8.150234] [check_input_term:860] reached
[    8.150766] [check_input_term:804] reached
[    8.151334] [check_input_term:860] reached
[    8.151927] [check_input_term:804] reached
[    8.152467] [check_input_term:860] reached
[    8.153026] [check_input_term:804] reached
........

[-- Attachment #3: trace1 --]
[-- Type: text/plain, Size: 5764 bytes --]

[   11.951264] usb 1-1: new high-speed USB device number 2 using xhci_hcd
[   12.078302] usb 1-1: Using ep0 maxpacket: 16
[   12.080698] usb 1-1: string descriptor 0 read error: -22
[   12.081917] usb 1-1: New USB device found, idVendor=046d, idProduct=0a44, bcdDevice= 1.27
[   12.083734] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[   12.090675] usb 1-1: current rate 16732531 is different from the runtime rate 48000
[   12.092985] usb 1-1: current rate 11254477 is different from the runtime rate 48000
[   12.105244] BUG: KASAN: use-after-free in tick_sched_handle+0x51/0x90
[   12.106010] Read of size 8 at addr ffff88815a1a9ed0 by task kworker/3:2/4772
[   12.106841]
[   12.107023] CPU: 3 PID: 4772 Comm: kworker/3:2 Not tainted 5.3.0-rc4+ #35
[   12.107841] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014
[   12.109200] Workqueue: usb_hub_wq hub_event
[   12.109734] Call Trace:
[   12.110023]  <IRQ>
[   12.110266]  dump_stack+0x5b/0x8b
[   12.110665]  ? tick_sched_handle+0x51/0x90
[   12.111163]  print_address_description+0x6e/0x390
[   12.111749]  ? tick_sched_handle+0x51/0x90
[   12.112221]  ? tick_sched_handle+0x51/0x90
[   12.112732]  __kasan_report+0x149/0x18d
[   12.113175]  ? tick_sched_handle+0x51/0x90
[   12.113681]  kasan_report+0xe/0x20
[   12.114076]  tick_sched_handle+0x51/0x90
[   12.114529]  tick_sched_timer+0x32/0x90
[   12.115007]  __hrtimer_run_queues+0x1f5/0x450
[   12.115514]  ? tick_sched_do_timer+0x80/0x80
[   12.116041]  ? enqueue_hrtimer+0x100/0x100
[   12.116514]  ? kvm_clock_get_cycles+0xd/0x10
[   12.117038]  ? ktime_get_update_offsets_now+0xa4/0x160
[   12.117659]  hrtimer_interrupt+0x192/0x350
[   12.118133]  smp_apic_timer_interrupt+0x83/0x1c0
[   12.118696]  apic_timer_interrupt+0xf/0x20
[   12.119174] WARNING: can't dereference registers at 00000000394dde74 for ip apic_timer_interrupt+0xf/0x20
[   12.119175]  </IRQ>
[   12.120550]
[   12.120751] Allocated by task 1511944392:
[   12.121216] BUG: unable to handle page fault for address: ffffffff8712da08
[   12.122029] #PF: supervisor read access in kernel mode
[   12.122649] #PF: error_code(0x0000) - not-present page
[   12.123239] PGD 4212067 P4D 4212067 PUD 4213063 PMD 0
[   12.123860] Thread overran stack, or stack corrupted
[   12.124534] Oops: 0000 [#1] SMP KASAN PTI
[   12.125009] CPU: 3 PID: 4772 Comm: kworker/3:2 Not tainted 5.3.0-rc4+ #35
[   12.125816] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.11.0-0-g63451fca13-prebuilt.qemu-project.org 04/01/2014
[   12.127172] Workqueue: usb_hub_wq hub_event
[   12.127689] RIP: 0010:stack_depot_fetch+0x10/0x30
[   12.128227] Code: ff 48 8b 73 18 48 89 ef 5b 5d e9 4b bb bd ff 0f 0b 90 90 90 90 90 90 90 90 90 89 f8 c1 ef 11 25 ff ff 1f 00 81 e7 f0 3f 00 00 <48> 03 3c c5 00 96 16 86 48 8d 47 18 48 89 06 8b 47 0c c3 0f 1f 00
[   12.130392] RSP: 0018:ffff88815b189d68 EFLAGS: 00010006
[   12.131022] RAX: 00000000001f8881 RBX: ffff88815a1aa100 RCX: ffffffff812150de
[   12.131867] RDX: 0000000000000000 RSI: ffff88815b189d70 RDI: 0000000000003ff0
[   12.132722] RBP: ffff88815a1a9ed0 R08: ffffed102b633ea3 R09: ffffed102b633ea3
[   12.133554] R10: 0000000000000001 R11: ffffed102b633ea2 R12: ffff88815a9017c0
[   12.134375] R13: ffff88815a1a9100 R14: ffff88815a1aa100 R15: ffff88815b1a5b00
[   12.135209] FS:  0000000000000000(0000) GS:ffff88815b180000(0000) knlGS:0000000000000000
[   12.136156] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   12.136845] CR2: ffffffff8712da08 CR3: 0000000152f26000 CR4: 00000000000006e0
[   12.137688] Call Trace:
[   12.137977]  <IRQ>
[   12.138218]  print_track+0x35/0x6b
[   12.138647]  print_address_description+0x335/0x390
[   12.139200]  ? tick_sched_handle+0x51/0x90
[   12.139706]  ? tick_sched_handle+0x51/0x90
[   12.140177]  __kasan_report+0x149/0x18d
[   12.140654]  ? tick_sched_handle+0x51/0x90
[   12.141126]  kasan_report+0xe/0x20
[   12.141557]  tick_sched_handle+0x51/0x90
[   12.142009]  tick_sched_timer+0x32/0x90
[   12.142486]  __hrtimer_run_queues+0x1f5/0x450
[   12.142986]  ? tick_sched_do_timer+0x80/0x80
[   12.143514]  ? enqueue_hrtimer+0x100/0x100
[   12.143986]  ? kvm_clock_get_cycles+0xd/0x10
[   12.144510]  ? ktime_get_update_offsets_now+0xa4/0x160
[   12.145097]  hrtimer_interrupt+0x192/0x350
[   12.145602]  smp_apic_timer_interrupt+0x83/0x1c0
[   12.146133]  apic_timer_interrupt+0xf/0x20
[   12.146637]  </IRQ>
[   12.146885] Modules linked in:
[   12.147277] CR2: ffffffff8712da08
[   12.147662] ---[ end trace 542cd123c33e7da5 ]---
[   12.148203] RIP: 0010:stack_depot_fetch+0x10/0x30
[   12.148765] Code: ff 48 8b 73 18 48 89 ef 5b 5d e9 4b bb bd ff 0f 0b 90 90 90 90 90 90 90 90 90 89 f8 c1 ef 11 25 ff ff 1f 00 81 e7 f0 3f 00 00 <48> 03 3c c5 00 96 16 86 48 8d 47 18 48 89 06 8b 47 0c c3 0f 1f 00
[   12.150932] RSP: 0018:ffff88815b189d68 EFLAGS: 00010006
[   12.151556] RAX: 00000000001f8881 RBX: ffff88815a1aa100 RCX: ffffffff812150de
[   12.152395] RDX: 0000000000000000 RSI: ffff88815b189d70 RDI: 0000000000003ff0
[   12.153233] RBP: ffff88815a1a9ed0 R08: ffffed102b633ea3 R09: ffffed102b633ea3
[   12.154039] R10: 0000000000000001 R11: ffffed102b633ea2 R12: ffff88815a9017c0
[   12.154973] R13: ffff88815a1a9100 R14: ffff88815a1aa100 R15: ffff88815b1a5b00
[   12.155830] FS:  0000000000000000(0000) GS:ffff88815b180000(0000) knlGS:0000000000000000
[   12.156777] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   12.157473] CR2: ffffffff8712da08 CR3: 0000000152f26000 CR4: 00000000000006e0
[   12.158320] Kernel panic - not syncing: Fatal exception in interrupt
[   12.159210] Kernel Offset: disabled
[   12.159642] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Fix a stack buffer overflow bug check_input_term
  2019-08-15  4:35 [PATCH] Fix a stack buffer overflow bug check_input_term Hui Peng
  2019-08-15  4:47 ` Hui Peng
@ 2019-08-15  6:13 ` Takashi Iwai
  2019-08-15  6:58   ` Takashi Iwai
  1 sibling, 1 reply; 6+ messages in thread
From: Takashi Iwai @ 2019-08-15  6:13 UTC (permalink / raw)
  To: Hui Peng
  Cc: security, alsa-devel, YueHaibing, Thomas Gleixner,
	Allison Randal, Mathias Payer, Jaroslav Kysela, Takashi Iwai,
	Wenwen Wang, linux-kernel

On Thu, 15 Aug 2019 06:35:49 +0200,
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@gmail.com>
> Reported-by: Mathias Payer <mathias.payer@nebelwelt.net>
> Signed-off-by: Hui Peng <benquike@gmail.com>

The fix looks almost good, but we need to be careful about the
bitmap check.  In theory, it's possible that multiple nodes point to
the same input terminal, and your patch would break that scenario.
For fixing that, we need to zero-clear the termbitmap at each first
invocation of check_input_term(), something like below.

Could you check whether this works?


thanks,

Takashi

--- 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;
@@ -773,14 +774,15 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state,
  * 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,
-			    struct usb_audio_term *term)
+static int __check_input_term(struct mixer_build *state, int id,
+			      struct usb_audio_term *term)
 {
 	int protocol = state->mixer->protocol;
 	int err;
 	void *p1;
 
-	memset(term, 0, sizeof(*term));
+	if (test_and_set_bit(id, state->termbitmap))
+		return 0;
 	while ((p1 = find_audio_control_unit(state, id)) != NULL) {
 		unsigned char *hdr = p1;
 		term->id = id;
@@ -800,7 +802,7 @@ static int check_input_term(struct mixer_build *state, int id,
 
 					/* 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;
 
@@ -834,7 +836,7 @@ static int check_input_term(struct mixer_build *state, int id,
 			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 = UAC3_SELECTOR_UNIT << 16; /* virtual type */
@@ -897,7 +899,7 @@ static int check_input_term(struct mixer_build *state, int id,
 
 				/* 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;
 
@@ -948,7 +950,7 @@ static int check_input_term(struct mixer_build *state, int id,
 			case UAC3_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 = UAC3_SELECTOR_UNIT << 16; /* virtual type */
@@ -964,7 +966,7 @@ static int check_input_term(struct mixer_build *state, int id,
 					return -EINVAL;
 
 				/* 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;
 
@@ -982,6 +984,14 @@ static int check_input_term(struct mixer_build *state, int id,
 	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
  */

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Fix a stack buffer overflow bug check_input_term
  2019-08-15  6:13 ` Takashi Iwai
@ 2019-08-15  6:58   ` Takashi Iwai
       [not found]     ` <CAKpmkkWCaLOctG44fD=arD-=oogRVCSxe5rz2UNUAms5q=2pYw@mail.gmail.com>
  0 siblings, 1 reply; 6+ messages in thread
From: Takashi Iwai @ 2019-08-15  6:58 UTC (permalink / raw)
  To: Hui Peng
  Cc: security, alsa-devel, YueHaibing, Thomas Gleixner,
	Allison Randal, Mathias Payer, Jaroslav Kysela, Takashi Iwai,
	Wenwen Wang, linux-kernel

On Thu, 15 Aug 2019 08:13:57 +0200,
Takashi Iwai wrote:
> 
> On Thu, 15 Aug 2019 06:35:49 +0200,
> 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@gmail.com>
> > Reported-by: Mathias Payer <mathias.payer@nebelwelt.net>
> > Signed-off-by: Hui Peng <benquike@gmail.com>
> 
> The fix looks almost good, but we need to be careful about the
> bitmap check.  In theory, it's possible that multiple nodes point to
> the same input terminal, and your patch would break that scenario.
> For fixing that, we need to zero-clear the termbitmap at each first
> invocation of check_input_term(), something like below.
> 
> Could you check whether this works?

Thinking of this further, there is another possible infinite loop.
Namely, when the feature unit in the input terminal chain points to
itself as the source, it'll loop endlessly without the stack
overflow.

So the check of the termbitmap should be inside the loop.
The revised patch is below.


thanks,

Takashi

-- 8< --
From: Hui Peng <benquike@gmail.com>
Subject: [PATCH] ALSA: usb-audio: 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).

[ The termbitmap needs to be cleared at each first check of the input
  terminal, so the function got split now.  Also, for catching another
  endless loop in the input terminal chain -- where the feature unit
  points to itself as its source -- the termbitmap check is moved
  inside the parser loop. -- tiwai ]

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>
---
 sound/usb/mixer.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index ea487378be17..aa8b046aa91f 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;
@@ -775,16 +776,23 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state,
  * 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,
-			    struct usb_audio_term *term)
+static int __check_input_term(struct mixer_build *state, int id,
+			      struct usb_audio_term *term)
 {
 	int protocol = state->mixer->protocol;
 	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))
+			break;
+
+		p1 = find_audio_control_unit(state, id);
+		if (!p1)
+			break;
+		hdr = p1;
 		term->id = id;
 
 		if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) {
@@ -802,7 +810,7 @@ static int check_input_term(struct mixer_build *state, int id,
 
 					/* 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;
 
@@ -836,7 +844,7 @@ static int check_input_term(struct mixer_build *state, int id,
 			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 = UAC3_SELECTOR_UNIT << 16; /* virtual type */
@@ -899,7 +907,7 @@ static int check_input_term(struct mixer_build *state, int id,
 
 				/* 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;
 
@@ -950,7 +958,7 @@ static int check_input_term(struct mixer_build *state, int id,
 			case UAC3_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 = UAC3_SELECTOR_UNIT << 16; /* virtual type */
@@ -966,7 +974,7 @@ static int check_input_term(struct mixer_build *state, int id,
 					return -EINVAL;
 
 				/* 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;
 
@@ -984,6 +992,14 @@ static int check_input_term(struct mixer_build *state, int id,
 	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
  */
-- 
2.16.4


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Fix a stack buffer overflow bug check_input_term
       [not found]     ` <CAKpmkkWCaLOctG44fD=arD-=oogRVCSxe5rz2UNUAms5q=2pYw@mail.gmail.com>
@ 2019-08-15 17:38       ` Takashi Iwai
       [not found]         ` <c6b11a34-3bd9-f1d7-cd27-4ddcd210a7cc@gmail.com>
  0 siblings, 1 reply; 6+ messages in thread
From: Takashi Iwai @ 2019-08-15 17:38 UTC (permalink / raw)
  To: Hui Peng
  Cc: security, alsa-devel, YueHaibing, Thomas Gleixner,
	Allison Randal, Mathias Payer, Jaroslav Kysela, Takashi Iwai,
	Wenwen Wang, linux-kernel

On Thu, 15 Aug 2019 19:19:10 +0200,
Hui Peng wrote:
> 
> Hi, Takashi:
> 
> One point I want to be clear: if an endless recursive loop is detected, should
> we return 0, or a negative error code? 

An error might be more appropriate, but it's no big deal, as you'll
likely hit other errors sooner or later at parsing further :)


thanks,

Takashi

> On Thu, Aug 15, 2019 at 2:58 AM Takashi Iwai <tiwai@suse.de> wrote:
> 
>     On Thu, 15 Aug 2019 08:13:57 +0200,
>     Takashi Iwai wrote:
>     >
>     > On Thu, 15 Aug 2019 06:35:49 +0200,
>     > 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@gmail.com>
>     > > Reported-by: Mathias Payer <mathias.payer@nebelwelt.net>
>     > > Signed-off-by: Hui Peng <benquike@gmail.com>
>     >
>     > The fix looks almost good, but we need to be careful about the
>     > bitmap check.  In theory, it's possible that multiple nodes point to
>     > the same input terminal, and your patch would break that scenario.
>     > For fixing that, we need to zero-clear the termbitmap at each first
>     > invocation of check_input_term(), something like below.
>     >
>     > Could you check whether this works?
>    
>     Thinking of this further, there is another possible infinite loop.
>     Namely, when the feature unit in the input terminal chain points to
>     itself as the source, it'll loop endlessly without the stack
>     overflow.
>    
>     So the check of the termbitmap should be inside the loop.
>     The revised patch is below.
> 
>     thanks,
>    
>     Takashi
>    
>     -- 8< --
>     From: Hui Peng <benquike@gmail.com>
>     Subject: [PATCH] ALSA: usb-audio: 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).
>    
>     [ The termbitmap needs to be cleared at each first check of the input
>       terminal, so the function got split now.  Also, for catching another
>       endless loop in the input terminal chain -- where the feature unit
>       points to itself as its source -- the termbitmap check is moved
>       inside the parser loop. -- tiwai ]
>    
>     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>
>     ---
>      sound/usb/mixer.c | 36 ++++++++++++++++++++++++++----------
>      1 file changed, 26 insertions(+), 10 deletions(-)
>    
>     diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
>     index ea487378be17..aa8b046aa91f 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;
>     @@ -775,16 +776,23 @@ static int uac_mixer_unit_get_channels(struct
>     mixer_build *state,
>       * 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,
>     -                           struct usb_audio_term *term)
>     +static int __check_input_term(struct mixer_build *state, int id,
>     +                             struct usb_audio_term *term)
>      {
>             int protocol = state->mixer->protocol;
>             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))
>     +                       break;
>     +
>     +               p1 = find_audio_control_unit(state, id);
>     +               if (!p1)
>     +                       break;
>     +               hdr = p1;
>                     term->id = id;
>    
>                     if (protocol == UAC_VERSION_1 || protocol ==
>     UAC_VERSION_2) {
>     @@ -802,7 +810,7 @@ static int check_input_term(struct mixer_build *state,
>     int id,
>    
>                                             /* 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;
>    
>     @@ -836,7 +844,7 @@ static int check_input_term(struct mixer_build *state,
>     int id,
>                             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 = UAC3_SELECTOR_UNIT << 16; /*
>     virtual type */
>     @@ -899,7 +907,7 @@ static int check_input_term(struct mixer_build *state,
>     int id,
>    
>                                     /* 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;
>    
>     @@ -950,7 +958,7 @@ static int check_input_term(struct mixer_build *state,
>     int id,
>                             case UAC3_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 = UAC3_SELECTOR_UNIT << 16; /*
>     virtual type */
>     @@ -966,7 +974,7 @@ static int check_input_term(struct mixer_build *state,
>     int id,
>                                             return -EINVAL;
>    
>                                     /* 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;
>    
>     @@ -984,6 +992,14 @@ static int check_input_term(struct mixer_build
>     *state, int id,
>             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
>       */
>     --
>     2.16.4
> 
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Fix a stack buffer overflow bug check_input_term
       [not found]         ` <c6b11a34-3bd9-f1d7-cd27-4ddcd210a7cc@gmail.com>
@ 2019-08-15 20:16           ` Takashi Iwai
  0 siblings, 0 replies; 6+ messages in thread
From: Takashi Iwai @ 2019-08-15 20:16 UTC (permalink / raw)
  To: Hui Peng
  Cc: security, alsa-devel, YueHaibing, Thomas Gleixner,
	Allison Randal, Mathias Payer, Jaroslav Kysela, Takashi Iwai,
	linux-kernel

On Thu, 15 Aug 2019 20:11:50 +0200,
Hui Peng wrote:
> 
> Hi, Takashi:
> 
> The new patch is confirmed (I made it to return -EINVAL if a endless
> recursive call is detected).
> Can you have a look.

OK, applied now.  Thanks.


Takashi

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-08-15 20:16 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-15  4:35 [PATCH] Fix a stack buffer overflow bug check_input_term Hui Peng
2019-08-15  4:47 ` Hui Peng
2019-08-15  6:13 ` Takashi Iwai
2019-08-15  6:58   ` Takashi Iwai
     [not found]     ` <CAKpmkkWCaLOctG44fD=arD-=oogRVCSxe5rz2UNUAms5q=2pYw@mail.gmail.com>
2019-08-15 17:38       ` Takashi Iwai
     [not found]         ` <c6b11a34-3bd9-f1d7-cd27-4ddcd210a7cc@gmail.com>
2019-08-15 20:16           ` Takashi Iwai

This is a public inbox, see mirroring instructions
on how to clone and mirror all data and code used for this inbox