[alsa-devel] [PATCH] Fix a stack buffer overflow bug check_input_term

Hui Peng benquike at gmail.com
Thu Aug 15 06:47:19 CEST 2019


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


More information about the Alsa-devel mailing list