Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751808AbdIUQne (ORCPT ); Thu, 21 Sep 2017 12:43:34 -0400 Received: from mail-io0-f181.google.com ([209.85.223.181]:47260 "EHLO mail-io0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751669AbdIUQnb (ORCPT ); Thu, 21 Sep 2017 12:43:31 -0400 X-Google-Smtp-Source: AOwi7QDZkoquvesmiNoxhZKxPOerxn1DQMTb9C4QNrZuVCIFnm4Z+Ums2MIqGhTS+7k2r6JNqa0szRA6JZYVCMCSxKM= MIME-Version: 1.0 From: Andrey Konovalov Date: Thu, 21 Sep 2017 18:43:29 +0200 Message-ID: Subject: usb/gadget: copy_to_user called with spinlock held To: Felipe Balbi , Greg Kroah-Hartman , Alan Stern , USB list , LKML Cc: Dmitry Vyukov , Kostya Serebryany , syzkaller Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 18299 Lines: 355 Hi! I've got the following report while fuzzing the kernel with syzkaller. On commit ebb2c2437d8008d46796902ff390653822af6cc4 (Sep 18). Line numbers might be a little off, due to some local changes to gadgetfs code but the issue is AFAIU with calling copy_to_user() with spinlock held in ep0_read(). I see that there's a FIXME exactly about that and I was wondering if there's any chance of getting this fixed? Thanks! BUG: sleeping function called from invalid context at lib/usercopy.c:24 in_atomic(): 1, irqs_disabled(): 1, pid: 5948, name: syz-executor0 2 locks held by syz-executor0/5948: #0: (&f->f_pos_lock){+.+.}, at: [] __fdget_pos+0x149/0x1c0 fs/file.c:767 #1: (&(&dev->lock)->rlock){..-.}, at: [] spin_lock_irq include/linux/spinlock.h:341 [inline] #1: (&(&dev->lock)->rlock){..-.}, at: [] ep0_read+0x580/0x1230 drivers/usb/gadget/legacy/inode.c:972 irq event stamp: 1220 hardirqs last enabled at (1219): [] __raw_spin_unlock_irq include/linux/spinlock_api_smp.h:168 [inline] hardirqs last enabled at (1219): [] _raw_spin_unlock_irq+0x2c/0x60 kernel/locking/spinlock.c:199 hardirqs last disabled at (1220): [] __raw_spin_lock_irq include/linux/spinlock_api_smp.h:126 [inline] hardirqs last disabled at (1220): [] _raw_spin_lock_irq+0x19/0x50 kernel/locking/spinlock.c:167 softirqs last enabled at (1022): [] __do_softirq+0x5fd/0xc2d kernel/softirq.c:310 softirqs last disabled at (1013): [] invoke_softirq kernel/softirq.c:364 [inline] softirqs last disabled at (1013): [] irq_exit+0x171/0x1a0 kernel/softirq.c:405 Preemption disabled at: [] spin_lock_irq include/linux/spinlock.h:341 [inline] [] ep0_read+0x580/0x1230 drivers/usb/gadget/legacy/inode.c:972 CPU: 1 PID: 5948 Comm: syz-executor0 Not tainted 4.14.0-rc1-42259-g18ca1418efd9 #216 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:16 [inline] dump_stack+0x292/0x395 lib/dump_stack.c:52 ___might_sleep+0x65c/0x720 kernel/sched/core.c:6015 __might_sleep+0x9a/0x190 kernel/sched/core.c:5968 __might_fault+0x15d/0x290 mm/memory.c:4499 _copy_to_user+0x2c/0xc0 lib/usercopy.c:24 copy_to_user include/linux/uaccess.h:154 [inline] ep0_read+0x739/0x1230 drivers/usb/gadget/legacy/inode.c:987 __vfs_read+0x69d/0x890 fs/read_write.c:410 vfs_read+0x129/0x360 fs/read_write.c:446 SYSC_read fs/read_write.c:572 [inline] SyS_read+0x100/0x240 fs/read_write.c:565 entry_SYSCALL_64_fastpath+0x23/0xc2 RIP: 0033:0x40cfb1 RSP: 002b:00007ff9c6b38b20 EFLAGS: 00000293 ORIG_RAX: 0000000000000000 RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 000000000040cfb1 RDX: 000000000000003c RSI: 00007ff9c6b38b70 RDI: 0000000000000005 RBP: 0000000000000005 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000293 R12: 0000000000708000 R13: 0000000000000000 R14: 00007ff9c6b399c0 R15: 00007ff9c6b39700 ===================================================== WARNING: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected 4.14.0-rc1-42259-g18ca1418efd9 #216 Tainted: G W ----------------------------------------------------- syz-executor0/5948 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire: (&mm->mmap_sem){++++}, at: [] __might_fault+0x18d/0x290 mm/memory.c:4501 and this task is already holding: (&(&dev->lock)->rlock){..-.}, at: [] spin_lock_irq include/linux/spinlock.h:341 [inline] (&(&dev->lock)->rlock){..-.}, at: [] ep0_read+0x580/0x1230 drivers/usb/gadget/legacy/inode.c:972 which would create a new lock dependency: (&(&dev->lock)->rlock){..-.} -> (&mm->mmap_sem){++++} but this new dependency connects a SOFTIRQ-irq-safe lock: (&(&dev->lock)->rlock){..-.} ... which became SOFTIRQ-irq-safe at: mark_irqflags kernel/locking/lockdep.c:3077 [inline] __lock_acquire+0x1d93/0x4550 kernel/locking/lockdep.c:3455 lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002 __raw_spin_lock include/linux/spinlock_api_smp.h:142 [inline] _raw_spin_lock+0x32/0x50 kernel/locking/spinlock.c:151 spin_lock include/linux/spinlock.h:316 [inline] gadgetfs_setup+0x212/0x1ea0 drivers/usb/gadget/legacy/inode.c:1320 dummy_timer+0x13bf/0x3970 drivers/usb/gadget/udc/dummy_hcd.c:1870 call_timer_fn+0x2a2/0x940 kernel/time/timer.c:1281 expire_timers kernel/time/timer.c:1320 [inline] __run_timers+0x87f/0xd40 kernel/time/timer.c:1620 run_timer_softirq+0x83/0x140 kernel/time/timer.c:1646 __do_softirq+0x305/0xc2d kernel/softirq.c:284 invoke_softirq kernel/softirq.c:364 [inline] irq_exit+0x171/0x1a0 kernel/softirq.c:405 exiting_irq arch/x86/include/asm/apic.h:638 [inline] smp_apic_timer_interrupt+0x2b9/0x8d0 arch/x86/kernel/apic/apic.c:1048 apic_timer_interrupt+0x9d/0xb0 arch/x86/entry/entry_64.S:577 native_safe_halt+0x6/0x10 arch/x86/include/asm/irqflags.h:53 arch_safe_halt arch/x86/include/asm/paravirt.h:93 [inline] default_idle+0x127/0x690 arch/x86/kernel/process.c:341 arch_cpu_idle+0xf/0x20 arch/x86/kernel/process.c:332 default_idle_call+0x3b/0x60 kernel/sched/idle.c:98 cpuidle_idle_call kernel/sched/idle.c:156 [inline] do_idle+0x35c/0x440 kernel/sched/idle.c:246 cpu_startup_entry+0x1d/0x20 kernel/sched/idle.c:351 start_secondary+0x3de/0x500 arch/x86/kernel/smpboot.c:277 verify_cpu+0x0/0xfb to a SOFTIRQ-irq-unsafe lock: (&mm->mmap_sem){++++} ... which became SOFTIRQ-irq-unsafe at: ... mark_irqflags kernel/locking/lockdep.c:3095 [inline] __lock_acquire+0x1024/0x4550 kernel/locking/lockdep.c:3455 lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002 down_write_killable+0x8a/0x150 kernel/locking/rwsem.c:67 __bprm_mm_init fs/exec.c:297 [inline] bprm_mm_init fs/exec.c:414 [inline] do_execveat_common.isra.31+0xc8f/0x2200 fs/exec.c:1767 do_execve+0x36/0x50 fs/exec.c:1842 run_init_process+0x37/0x40 init/main.c:943 try_to_run_init_process+0x1c/0x50 init/main.c:952 kernel_init+0xfd/0x180 init/main.c:1025 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431 other info that might help us debug this: Possible interrupt unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&mm->mmap_sem); local_irq_disable(); lock(&(&dev->lock)->rlock); lock(&mm->mmap_sem); lock(&(&dev->lock)->rlock); *** DEADLOCK *** 2 locks held by syz-executor0/5948: #0: (&f->f_pos_lock){+.+.}, at: [] __fdget_pos+0x149/0x1c0 fs/file.c:767 #1: (&(&dev->lock)->rlock){..-.}, at: [] spin_lock_irq include/linux/spinlock.h:341 [inline] #1: (&(&dev->lock)->rlock){..-.}, at: [] ep0_read+0x580/0x1230 drivers/usb/gadget/legacy/inode.c:972 the dependencies between SOFTIRQ-irq-safe lock and the holding lock: -> (&(&dev->lock)->rlock){..-.} ops: 27637 { IN-SOFTIRQ-W at: mark_irqflags kernel/locking/lockdep.c:3077 [inline] __lock_acquire+0x1d93/0x4550 kernel/locking/lockdep.c:3455 lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002 __raw_spin_lock include/linux/spinlock_api_smp.h:142 [inline] _raw_spin_lock+0x32/0x50 kernel/locking/spinlock.c:151 spin_lock include/linux/spinlock.h:316 [inline] gadgetfs_setup+0x212/0x1ea0 drivers/usb/gadget/legacy/inode.c:1320 dummy_timer+0x13bf/0x3970 drivers/usb/gadget/udc/dummy_hcd.c:1870 call_timer_fn+0x2a2/0x940 kernel/time/timer.c:1281 expire_timers kernel/time/timer.c:1320 [inline] __run_timers+0x87f/0xd40 kernel/time/timer.c:1620 run_timer_softirq+0x83/0x140 kernel/time/timer.c:1646 __do_softirq+0x305/0xc2d kernel/softirq.c:284 invoke_softirq kernel/softirq.c:364 [inline] irq_exit+0x171/0x1a0 kernel/softirq.c:405 exiting_irq arch/x86/include/asm/apic.h:638 [inline] smp_apic_timer_interrupt+0x2b9/0x8d0 arch/x86/kernel/apic/apic.c:1048 apic_timer_interrupt+0x9d/0xb0 arch/x86/entry/entry_64.S:577 native_safe_halt+0x6/0x10 arch/x86/include/asm/irqflags.h:53 arch_safe_halt arch/x86/include/asm/paravirt.h:93 [inline] default_idle+0x127/0x690 arch/x86/kernel/process.c:341 arch_cpu_idle+0xf/0x20 arch/x86/kernel/process.c:332 default_idle_call+0x3b/0x60 kernel/sched/idle.c:98 cpuidle_idle_call kernel/sched/idle.c:156 [inline] do_idle+0x35c/0x440 kernel/sched/idle.c:246 cpu_startup_entry+0x1d/0x20 kernel/sched/idle.c:351 start_secondary+0x3de/0x500 arch/x86/kernel/smpboot.c:277 verify_cpu+0x0/0xfb INITIAL USE at: __lock_acquire+0x7aa/0x4550 kernel/locking/lockdep.c:3459 lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002 __raw_spin_lock_irq include/linux/spinlock_api_smp.h:128 [inline] _raw_spin_lock_irq+0x3e/0x50 kernel/locking/spinlock.c:167 dev_open+0x48/0x140 drivers/media/usb/gspca/gspca.c:1286 do_dentry_open+0x74e/0xd60 fs/open.c:752 vfs_open+0x10c/0x230 fs/open.c:866 do_last fs/namei.c:3387 [inline] path_openat+0xf22/0x34d0 fs/namei.c:3527 do_filp_open+0x2a1/0x460 fs/namei.c:3562 do_sys_open+0x543/0x720 fs/open.c:1059 SYSC_open fs/open.c:1077 [inline] SyS_open+0x32/0x40 fs/open.c:1072 entry_SYSCALL_64_fastpath+0x23/0xc2 } ... key at: [] __key.35734+0x0/0x40 ... acquired at: check_irq_usage kernel/locking/lockdep.c:1694 [inline] check_prev_add_irq kernel/locking/lockdep_states.h:8 [inline] check_prev_add+0x319/0x1780 kernel/locking/lockdep.c:1898 check_prevs_add kernel/locking/lockdep.c:2020 [inline] validate_chain kernel/locking/lockdep.c:2469 [inline] __lock_acquire+0x3296/0x4550 kernel/locking/lockdep.c:3498 lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002 __might_fault+0x213/0x290 mm/memory.c:4502 _copy_to_user+0x2c/0xc0 lib/usercopy.c:24 copy_to_user include/linux/uaccess.h:154 [inline] ep0_read+0x739/0x1230 drivers/usb/gadget/legacy/inode.c:987 __vfs_read+0x69d/0x890 fs/read_write.c:410 vfs_read+0x129/0x360 fs/read_write.c:446 SYSC_read fs/read_write.c:572 [inline] SyS_read+0x100/0x240 fs/read_write.c:565 entry_SYSCALL_64_fastpath+0x23/0xc2 the dependencies between the lock to be acquired and SOFTIRQ-irq-unsafe lock: -> (&mm->mmap_sem){++++} ops: 1801476 { HARDIRQ-ON-W at: mark_irqflags kernel/locking/lockdep.c:3091 [inline] __lock_acquire+0xfb7/0x4550 kernel/locking/lockdep.c:3455 lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002 down_write_killable+0x8a/0x150 kernel/locking/rwsem.c:67 __bprm_mm_init fs/exec.c:297 [inline] bprm_mm_init fs/exec.c:414 [inline] do_execveat_common.isra.31+0xc8f/0x2200 fs/exec.c:1767 do_execve+0x36/0x50 fs/exec.c:1842 run_init_process+0x37/0x40 init/main.c:943 try_to_run_init_process+0x1c/0x50 init/main.c:952 kernel_init+0xfd/0x180 init/main.c:1025 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431 HARDIRQ-ON-R at: mark_irqflags kernel/locking/lockdep.c:3083 [inline] __lock_acquire+0x70d/0x4550 kernel/locking/lockdep.c:3455 lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002 __might_fault+0x213/0x290 mm/memory.c:4502 __clear_user+0x28/0x70 arch/x86/lib/usercopy_64.c:19 clear_user+0x7e/0xb0 arch/x86/lib/usercopy_64.c:53 padzero fs/binfmt_elf.c:129 [inline] load_elf_binary+0x3940/0x4fa0 fs/binfmt_elf.c:1058 search_binary_handler+0x146/0x480 fs/exec.c:1634 exec_binprm fs/exec.c:1676 [inline] do_execveat_common.isra.31+0x16d2/0x2200 fs/exec.c:1798 do_execve+0x36/0x50 fs/exec.c:1842 run_init_process+0x37/0x40 init/main.c:943 try_to_run_init_process+0x1c/0x50 init/main.c:952 kernel_init+0xfd/0x180 init/main.c:1025 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431 SOFTIRQ-ON-W at: mark_irqflags kernel/locking/lockdep.c:3095 [inline] __lock_acquire+0x1024/0x4550 kernel/locking/lockdep.c:3455 lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002 down_write_killable+0x8a/0x150 kernel/locking/rwsem.c:67 __bprm_mm_init fs/exec.c:297 [inline] bprm_mm_init fs/exec.c:414 [inline] do_execveat_common.isra.31+0xc8f/0x2200 fs/exec.c:1767 do_execve+0x36/0x50 fs/exec.c:1842 run_init_process+0x37/0x40 init/main.c:943 try_to_run_init_process+0x1c/0x50 init/main.c:952 kernel_init+0xfd/0x180 init/main.c:1025 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431 SOFTIRQ-ON-R at: mark_irqflags kernel/locking/lockdep.c:3087 [inline] __lock_acquire+0x776/0x4550 kernel/locking/lockdep.c:3455 lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002 __might_fault+0x213/0x290 mm/memory.c:4502 __clear_user+0x28/0x70 arch/x86/lib/usercopy_64.c:19 clear_user+0x7e/0xb0 arch/x86/lib/usercopy_64.c:53 padzero fs/binfmt_elf.c:129 [inline] load_elf_binary+0x3940/0x4fa0 fs/binfmt_elf.c:1058 search_binary_handler+0x146/0x480 fs/exec.c:1634 exec_binprm fs/exec.c:1676 [inline] do_execveat_common.isra.31+0x16d2/0x2200 fs/exec.c:1798 do_execve+0x36/0x50 fs/exec.c:1842 run_init_process+0x37/0x40 init/main.c:943 try_to_run_init_process+0x1c/0x50 init/main.c:952 kernel_init+0xfd/0x180 init/main.c:1025 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431 INITIAL USE at: __lock_acquire+0x7aa/0x4550 kernel/locking/lockdep.c:3459 lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002 down_write_killable+0x8a/0x150 kernel/locking/rwsem.c:67 __bprm_mm_init fs/exec.c:297 [inline] bprm_mm_init fs/exec.c:414 [inline] do_execveat_common.isra.31+0xc8f/0x2200 fs/exec.c:1767 do_execve+0x36/0x50 fs/exec.c:1842 run_init_process+0x37/0x40 init/main.c:943 try_to_run_init_process+0x1c/0x50 init/main.c:952 kernel_init+0xfd/0x180 init/main.c:1025 ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431 } ... key at: [] __key.64135+0x0/0x40 ... acquired at: check_irq_usage kernel/locking/lockdep.c:1694 [inline] check_prev_add_irq kernel/locking/lockdep_states.h:8 [inline] check_prev_add+0x319/0x1780 kernel/locking/lockdep.c:1898 check_prevs_add kernel/locking/lockdep.c:2020 [inline] validate_chain kernel/locking/lockdep.c:2469 [inline] __lock_acquire+0x3296/0x4550 kernel/locking/lockdep.c:3498 lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002 __might_fault+0x213/0x290 mm/memory.c:4502 _copy_to_user+0x2c/0xc0 lib/usercopy.c:24 copy_to_user include/linux/uaccess.h:154 [inline] ep0_read+0x739/0x1230 drivers/usb/gadget/legacy/inode.c:987 __vfs_read+0x69d/0x890 fs/read_write.c:410 vfs_read+0x129/0x360 fs/read_write.c:446 SYSC_read fs/read_write.c:572 [inline] SyS_read+0x100/0x240 fs/read_write.c:565 entry_SYSCALL_64_fastpath+0x23/0xc2 stack backtrace: CPU: 1 PID: 5948 Comm: syz-executor0 Tainted: G W 4.14.0-rc1-42259-g18ca1418efd9 #216 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:16 [inline] dump_stack+0x292/0x395 lib/dump_stack.c:52 print_bad_irq_dependency kernel/locking/lockdep.c:1606 [inline] check_usage+0xc46/0xc90 kernel/locking/lockdep.c:1638 check_irq_usage kernel/locking/lockdep.c:1694 [inline] check_prev_add_irq kernel/locking/lockdep_states.h:8 [inline] check_prev_add+0x319/0x1780 kernel/locking/lockdep.c:1898 check_prevs_add kernel/locking/lockdep.c:2020 [inline] validate_chain kernel/locking/lockdep.c:2469 [inline] __lock_acquire+0x3296/0x4550 kernel/locking/lockdep.c:3498 lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002 __might_fault+0x213/0x290 mm/memory.c:4502 _copy_to_user+0x2c/0xc0 lib/usercopy.c:24 copy_to_user include/linux/uaccess.h:154 [inline] ep0_read+0x739/0x1230 drivers/usb/gadget/legacy/inode.c:987 __vfs_read+0x69d/0x890 fs/read_write.c:410 vfs_read+0x129/0x360 fs/read_write.c:446 SYSC_read fs/read_write.c:572 [inline] SyS_read+0x100/0x240 fs/read_write.c:565 entry_SYSCALL_64_fastpath+0x23/0xc2 RIP: 0033:0x40cfb1 RSP: 002b:00007ff9c6b38b20 EFLAGS: 00000293 ORIG_RAX: 0000000000000000 RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 000000000040cfb1 RDX: 000000000000003c RSI: 00007ff9c6b38b70 RDI: 0000000000000005 RBP: 0000000000000005 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000293 R12: 0000000000708000 R13: 0000000000000000 R14: 00007ff9c6b399c0 R15: 00007ff9c6b39700