Re: usb/gadget: use-after-free in gadgetfs_setup

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Dec 9, 2016 at 8:57 PM, Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote:
> On Fri, 9 Dec 2016, Andrey Konovalov wrote:
>
>> On Wed, Dec 7, 2016 at 8:15 PM, Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote:
>> > On Wed, 7 Dec 2016, Andrey Konovalov wrote:
>> >
>> >> > And in any case, is there any way you can post the series of system
>> >> > calls that syzkaller makes so we can tell what went wrong?
>> >>
>> >> I've attached a reproducer for a use-after-free in gadgetfs_setup().
>> >> You need to enable KASAN to see the reports.
>> >
>> > Okay, that helps.  I see the problem: dev->hs_config ends up containing
>> > a stale pointer in dev_config().  The patch below ought to fix that;
>> > please verify that it really does.
>>
>> Hi Alan,
>>
>> Have been fuzzing with your patch, haven't seen any more reports.
>>
>> Thanks!
>
> Okay, good.  I'll submit the two patches.
>
> Can you also provide reproducers for the "GPF in
> usb_gadget_unregister_driver" and the "warning in dummy_free_request"
> tests?

Hi Alan,

I haven't managed to obtain a working reproducer, though the fuzzer
hits it pretty often :(

Here is a syzkaller description of the program which triggers the
crash (note that syzkaller can run each call concurrently):

mmap(&(0x7f0000000000/0x5000)=nil, (0x5000), 0x3, 0x32, 0xffffffffffffffff, 0x0)
r0 = open$usb(&(0x7f0000000000)="2f6465762f6761646765742f64756d6d795f75646300",
0x602, 0x0)
read$usb(r0, &(0x7f0000000000)="000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
0xcf)
write$usb(r0, &(0x7f0000003000-0x28)={0x0, {0x9, 0x2, 0x12,
0xffffffffffffff9e, 0x83, 0x5, 0x80, 0x0}, {0x9, 0x4, 0x0, 0x0, 0x0,
0x0, 0x55, 0x4, 0x9}, {0x12, 0x1, 0x2, 0x8001, 0x8, 0x6, 0x0, 0x0,
0x2, 0x2, 0x0, 0x0, 0x7, 0x1}}, 0x28)
read$usb(r0, &(0x7f0000004000-0xf)="000000000000000000000000", 0xc)
read$usb(r0, &(0x7f0000004000)="00000000000000000000000000000000000000000000000000000000",
0x1c)

The second argument of write$usb (which is probably the most
interesting call) is a structure of the following format:

usb_init {
  tag const[0, int32]
  config usb_config_descriptor
  interface usb_interface_descriptor
  device usb_device_descriptor
} [packed]

usb_config_descriptor, usb_interface_descriptor and
usb_device_descriptor correspond to kernel structures as defined in
include/uapi/linux/usb/ch9.h

I noticed that both reports happen one after another on the same testcase.
Below a part of the kernel log with both reports.

I hope some of that helps.

gadgetfs: bound to dummy_udc driver
usb 1-1: new full-speed USB device number 6 using dummy_hcd
gadgetfs: connected
gadgetfs: disconnected
gadgetfs: connected
usb 1-1: config 131 has too many interfaces: 158, using maximum allowed: 32
usb 1-1: config 131 has 1 interface, different from the descriptor's value: 158
gadgetfs: disconnected
------------[ cut here ]------------
WARNING: CPU: 0 PID: 4410 at drivers/usb/gadget/udc/dummy_hcd.c:672
dummy_free_request+0x153/0x170
Modules linked in:
CPU: 0 PID: 4410 Comm: syz-executor Not tainted 4.9.0-rc7+ #32
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
 ffff88006a64ed10 ffffffff81f96b8a ffffffff41b58ab3 1ffff1000d4c9d35
 ffffed000d4c9d2d ffff880065f8ac00 0000000041b58ab3 ffffffff8598b510
 ffffffff81f968f8 0000000041b58ab3 ffffffff859410e0 ffffffff813f0590
Call Trace:
 [<     inline     >] __dump_stack lib/dump_stack.c:15
 [<ffffffff81f96b8a>] dump_stack+0x292/0x398 lib/dump_stack.c:51
 [<ffffffff812b808f>] __warn+0x19f/0x1e0 kernel/panic.c:550
 [<ffffffff812b831c>] warn_slowpath_null+0x2c/0x40 kernel/panic.c:585
 [<ffffffff830fcb13>] dummy_free_request+0x153/0x170
drivers/usb/gadget/udc/dummy_hcd.c:672
 [<ffffffff830ed1b0>] usb_ep_free_request+0xc0/0x420
drivers/usb/gadget/udc/core.c:195
 [<ffffffff83225031>] gadgetfs_unbind+0x131/0x190
drivers/usb/gadget/legacy/inode.c:1612
 [<ffffffff830ebd8f>] usb_gadget_remove_driver+0x10f/0x2b0
drivers/usb/gadget/udc/core.c:1228
 [<ffffffff830ec084>] usb_gadget_unregister_driver+0x154/0x240
drivers/usb/gadget/udc/core.c:1357
 [<ffffffff832246a0>] dev_release+0x80/0x160
drivers/usb/gadget/legacy/inode.c:1187
 [<ffffffff81805922>] __fput+0x332/0x7f0 fs/file_table.c:208
 [<ffffffff81805e65>] ____fput+0x15/0x20 fs/file_table.c:244
 [<ffffffff81338b9b>] task_work_run+0x19b/0x270 kernel/task_work.c:116
 [<     inline     >] exit_task_work ./include/linux/task_work.h:21
 [<ffffffff812c7eca>] do_exit+0x16aa/0x2530 kernel/exit.c:828
 [<ffffffff812cd749>] do_group_exit+0x149/0x420 kernel/exit.c:932
 [<ffffffff812faa9d>] get_signal+0x76d/0x17b0 kernel/signal.c:2307
 [<ffffffff811cfee2>] do_signal+0xd2/0x2120 arch/x86/kernel/signal.c:807
 [<ffffffff81003d00>] exit_to_usermode_loop+0x170/0x200
arch/x86/entry/common.c:156
 [<     inline     >] prepare_exit_to_usermode arch/x86/entry/common.c:190
 [<ffffffff81007293>] syscall_return_slowpath+0x3d3/0x420
arch/x86/entry/common.c:259
 [<ffffffff84f47f62>] entry_SYSCALL_64_fastpath+0xc0/0xc2
arch/x86/entry/entry_64.S:244
---[ end trace 4dd5ab6469ba43ff ]---
usb 1-1: string descriptor 0 read error: -71
usb 1-1: New USB device found, idVendor=0000, idProduct=0002
usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=7
usb 1-1: can't set config #131, error -71
usb 1-1: USB disconnect, device number 6
gadgetfs: bound to dummy_udc driver
usb 1-1: new full-speed USB device number 7 using dummy_hcd
==================================================================
BUG: KASAN: use-after-free in __list_del_entry+0x267/0x280 at addr
ffff88006bdf3308
Read of size 8 by task kworker/u4:4/1272
CPU: 1 PID: 1272 Comm: kworker/u4:4 Tainted: G        W       4.9.0-rc7+ #32
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Workqueue: events_unbound flush_to_ldisc
 ffff88006cb06c58 ffffffff81f96b8a ffffffff0d960d1d 1ffff1000d960d1e
 ffffed000d960d16 ffff88006cb06d48 0000000041b58ab3 ffffffff8598b510
 ffffffff81f968f8 0000000000000000 ffff88006a3ddb80 ffffffff817e45a5
Call Trace:
 <IRQ> [   47.734047]  [<ffffffff81f96b8a>] dump_stack+0x292/0x398
 [<ffffffff817e4ebc>] kasan_object_err+0x1c/0x70 mm/kasan/report.c:159
 [<     inline     >] print_address_description mm/kasan/report.c:197
 [<ffffffff817e5150>] kasan_report_error+0x1f0/0x4e0 mm/kasan/report.c:286
 [<     inline     >] kasan_report mm/kasan/report.c:306
 [<ffffffff817e553e>] __asan_report_load8_noabort+0x3e/0x40
mm/kasan/report.c:327
 [<ffffffff8201ad07>] __list_del_entry+0x267/0x280 lib/list_debug.c:48
 [<     inline     >] list_del_init ./include/linux/list.h:145
 [<ffffffff830ff76d>] dummy_timer+0x2c3d/0x36d0
drivers/usb/gadget/udc/dummy_hcd.c:1830
 [<ffffffff81480891>] call_timer_fn+0x241/0x800 kernel/time/timer.c:1308
 [<     inline     >] expire_timers kernel/time/timer.c:1348
 [<ffffffff81482eb6>] __run_timers+0xa06/0xec0 kernel/time/timer.c:1641
 [<ffffffff81483391>] run_timer_softirq+0x21/0x80 kernel/time/timer.c:1654
 [<ffffffff84f4af8b>] __do_softirq+0x2fb/0xb63 kernel/softirq.c:284
 [<     inline     >] invoke_softirq kernel/softirq.c:364
 [<ffffffff812d3b8e>] irq_exit+0x19e/0x1d0 kernel/softirq.c:405
 [<     inline     >] exiting_irq ./arch/x86/include/asm/apic.h:659
 [<ffffffff84f4a59b>] smp_apic_timer_interrupt+0x7b/0xa0
arch/x86/kernel/apic/apic.c:960
 [<ffffffff84f4964c>] apic_timer_interrupt+0x8c/0xa0
 <EOI> [   47.826339]  [<ffffffff81465fa4>] ? rcu_all_qs+0x114/0x230
 [<ffffffff81327a2d>] process_one_work+0x111d/0x1aa0 kernel/workqueue.c:2122
 [<ffffffff813285bf>] worker_thread+0x20f/0x18a0 kernel/workqueue.c:2230
 [<ffffffff8133ebf3>] kthread+0x323/0x3e0 kernel/kthread.c:209
 [<ffffffff84f4812a>] ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:433
Object at ffff88006bdf3300, in cache kmalloc-128 size: 128
Allocated:
PID = 4410
[<ffffffff81203526>] save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57
[<ffffffff817e41a3>] save_stack+0x43/0xd0 mm/kasan/kasan.c:495
[<     inline     >] set_track mm/kasan/kasan.c:507
[<ffffffff817e442d>] kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:598
[<ffffffff817dfad2>] kmem_cache_alloc_trace+0x82/0x270 mm/slub.c:2735
[<     inline     >] kmalloc ./include/linux/slab.h:490
[<     inline     >] kzalloc ./include/linux/slab.h:636
[<ffffffff83100f9b>] dummy_alloc_request+0x17b/0x1b0
drivers/usb/gadget/udc/dummy_hcd.c:655
[<ffffffff830e5c60>] usb_ep_alloc_request+0xc0/0x460
drivers/usb/gadget/udc/core.c:175
[<ffffffff83226e1c>] gadgetfs_bind+0x19c/0x850
drivers/usb/gadget/legacy/inode.c:1637
[<ffffffff830eb8c0>] udc_bind_to_driver+0xe0/0x4a0
drivers/usb/gadget/udc/core.c:1283
[<ffffffff830ec6c1>] usb_gadget_probe_driver+0x2d1/0x3c0
drivers/usb/gadget/udc/core.c:1340
[<ffffffff83228cdc>] dev_config+0x84c/0x1480
drivers/usb/gadget/legacy/inode.c:1831
[<ffffffff817fde25>] __vfs_write+0x5d5/0x760 fs/read_write.c:510
[<ffffffff817ff720>] vfs_write+0x170/0x4e0 fs/read_write.c:560
[<     inline     >] SYSC_write fs/read_write.c:607
[<ffffffff81803b2b>] SyS_write+0xfb/0x230 fs/read_write.c:599
[<ffffffff84f47ec1>] entry_SYSCALL_64_fastpath+0x1f/0xc2
arch/x86/entry/entry_64.S:209
Freed:
PID = 4410
[<ffffffff81203526>] save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57
[<ffffffff817e41a3>] save_stack+0x43/0xd0 mm/kasan/kasan.c:495
[<     inline     >] set_track mm/kasan/kasan.c:507
[<ffffffff817e4a83>] kasan_slab_free+0x73/0xc0 mm/kasan/kasan.c:571
[<     inline     >] slab_free_hook mm/slub.c:1352
[<     inline     >] slab_free_freelist_hook mm/slub.c:1374
[<     inline     >] slab_free mm/slub.c:2951
[<ffffffff817e0ee7>] kfree+0xe7/0x2b0 mm/slub.c:3871
[<ffffffff830fcaae>] dummy_free_request+0xee/0x170
drivers/usb/gadget/udc/dummy_hcd.c:673
[<ffffffff830ed1b0>] usb_ep_free_request+0xc0/0x420
drivers/usb/gadget/udc/core.c:195
[<ffffffff83225031>] gadgetfs_unbind+0x131/0x190
drivers/usb/gadget/legacy/inode.c:1612
[<ffffffff830ebd8f>] usb_gadget_remove_driver+0x10f/0x2b0
drivers/usb/gadget/udc/core.c:1228
[<ffffffff830ec084>] usb_gadget_unregister_driver+0x154/0x240
drivers/usb/gadget/udc/core.c:1357
[<ffffffff832246a0>] dev_release+0x80/0x160
drivers/usb/gadget/legacy/inode.c:1187
[<ffffffff81805922>] __fput+0x332/0x7f0 fs/file_table.c:208
[<ffffffff81805e65>] ____fput+0x15/0x20 fs/file_table.c:244
[<ffffffff81338b9b>] task_work_run+0x19b/0x270 kernel/task_work.c:116
[<     inline     >] exit_task_work ./include/linux/task_work.h:21
[<ffffffff812c7eca>] do_exit+0x16aa/0x2530 kernel/exit.c:828
[<ffffffff812cd749>] do_group_exit+0x149/0x420 kernel/exit.c:932
[<ffffffff812faa9d>] get_signal+0x76d/0x17b0 kernel/signal.c:2307
[<ffffffff811cfee2>] do_signal+0xd2/0x2120 arch/x86/kernel/signal.c:807
[<ffffffff81003d00>] exit_to_usermode_loop+0x170/0x200
arch/x86/entry/common.c:156
[<     inline     >] prepare_exit_to_usermode arch/x86/entry/common.c:190
[<ffffffff81007293>] syscall_return_slowpath+0x3d3/0x420
arch/x86/entry/common.c:259
[<ffffffff84f47f62>] entry_SYSCALL_64_fastpath+0xc0/0xc2
arch/x86/entry/entry_64.S:244
Memory state around the buggy address:
 ffff88006bdf3200: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
 ffff88006bdf3280: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>ffff88006bdf3300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                      ^
 ffff88006bdf3380: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
 ffff88006bdf3400: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
==================================================================

>
> Alan Stern
>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux