usb/gadget: copy_to_user called with spinlock held

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

 



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: [<ffffffff81892809>]
__fdget_pos+0x149/0x1c0 fs/file.c:767
 #1:  (&(&dev->lock)->rlock){..-.}, at: [<ffffffff837b42d0>]
spin_lock_irq include/linux/spinlock.h:341 [inline]
 #1:  (&(&dev->lock)->rlock){..-.}, at: [<ffffffff837b42d0>]
ep0_read+0x580/0x1230 drivers/usb/gadget/legacy/inode.c:972
irq event stamp: 1220
hardirqs last  enabled at (1219): [<ffffffff856cec8c>]
__raw_spin_unlock_irq include/linux/spinlock_api_smp.h:168 [inline]
hardirqs last  enabled at (1219): [<ffffffff856cec8c>]
_raw_spin_unlock_irq+0x2c/0x60 kernel/locking/spinlock.c:199
hardirqs last disabled at (1220): [<ffffffff856ce989>]
__raw_spin_lock_irq include/linux/spinlock_api_smp.h:126 [inline]
hardirqs last disabled at (1220): [<ffffffff856ce989>]
_raw_spin_lock_irq+0x19/0x50 kernel/locking/spinlock.c:167
softirqs last  enabled at (1022): [<ffffffff856d81dd>]
__do_softirq+0x5fd/0xc2d kernel/softirq.c:310
softirqs last disabled at (1013): [<ffffffff811924f1>] invoke_softirq
kernel/softirq.c:364 [inline]
softirqs last disabled at (1013): [<ffffffff811924f1>]
irq_exit+0x171/0x1a0 kernel/softirq.c:405
Preemption disabled at:
[<ffffffff837b42d0>] spin_lock_irq include/linux/spinlock.h:341 [inline]
[<ffffffff837b42d0>] 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: [<ffffffff816eb04d>]
__might_fault+0x18d/0x290 mm/memory.c:4501

and this task is already holding:
 (&(&dev->lock)->rlock){..-.}, at: [<ffffffff837b42d0>] spin_lock_irq
include/linux/spinlock.h:341 [inline]
 (&(&dev->lock)->rlock){..-.}, at: [<ffffffff837b42d0>]
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);
  <Interrupt>
    lock(&(&dev->lock)->rlock);

 *** DEADLOCK ***

2 locks held by syz-executor0/5948:
 #0:  (&f->f_pos_lock){+.+.}, at: [<ffffffff81892809>]
__fdget_pos+0x149/0x1c0 fs/file.c:767
 #1:  (&(&dev->lock)->rlock){..-.}, at: [<ffffffff837b42d0>]
spin_lock_irq include/linux/spinlock.h:341 [inline]
 #1:  (&(&dev->lock)->rlock){..-.}, at: [<ffffffff837b42d0>]
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: [<ffffffff88779940>] __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: [<ffffffff87303540>] __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
--
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