* [syzbot] INFO: task hung in do_proc_bulk @ 2021-08-28 15:52 syzbot 2021-08-28 18:03 ` Alan Stern 2021-09-02 20:04 ` [syzbot] INFO: task hung in do_proc_bulk Alan Stern 0 siblings, 2 replies; 17+ messages in thread From: syzbot @ 2021-08-28 15:52 UTC (permalink / raw) To: gregkh, johan, linux-kernel, linux-usb, mathias.nyman, stern, syzkaller-bugs Hello, syzbot found the following issue on: HEAD commit: d5ae8d7f85b7 Revert "media: dvb header files: move some he.. git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=155fa21e300000 kernel config: https://syzkaller.appspot.com/x/.config?x=2fd902af77ff1e56 dashboard link: https://syzkaller.appspot.com/bug?extid=ada0f7d3d9fd2016d927 compiler: Debian clang version 11.0.1-2, GNU ld (GNU Binutils for Debian) 2.35.1 syz repro: https://syzkaller.appspot.com/x/repro.syz?x=11a1ab0e300000 Bisection is inconclusive: the issue happens on the oldest tested release. bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=15662ee1300000 final oops: https://syzkaller.appspot.com/x/report.txt?x=17662ee1300000 console output: https://syzkaller.appspot.com/x/log.txt?x=13662ee1300000 IMPORTANT: if you fix the issue, please add the following tag to the commit: Reported-by: syzbot+ada0f7d3d9fd2016d927@syzkaller.appspotmail.com INFO: task syz-executor.0:8700 blocked for more than 143 seconds. Not tainted 5.14.0-rc7-syzkaller #0 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:syz-executor.0 state:D stack:23192 pid: 8700 ppid: 8455 flags:0x00004004 Call Trace: context_switch kernel/sched/core.c:4681 [inline] __schedule+0xc07/0x11f0 kernel/sched/core.c:5938 schedule+0x14b/0x210 kernel/sched/core.c:6017 schedule_timeout+0x98/0x2f0 kernel/time/timer.c:1857 do_wait_for_common+0x2da/0x480 kernel/sched/completion.c:85 __wait_for_common kernel/sched/completion.c:106 [inline] wait_for_common kernel/sched/completion.c:117 [inline] wait_for_completion_timeout+0x46/0x60 kernel/sched/completion.c:157 usb_start_wait_urb+0x167/0x550 drivers/usb/core/message.c:63 do_proc_bulk+0x978/0x1080 drivers/usb/core/devio.c:1236 proc_bulk drivers/usb/core/devio.c:1273 [inline] usbdev_do_ioctl drivers/usb/core/devio.c:2547 [inline] usbdev_ioctl+0x3441/0x6b10 drivers/usb/core/devio.c:2713 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:1069 [inline] __se_sys_ioctl+0xfb/0x170 fs/ioctl.c:1055 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x4665e9 RSP: 002b:00007f15a90dc188 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 000000000056bf80 RCX: 00000000004665e9 RDX: 0000000020000340 RSI: 00000000c0185502 RDI: 0000000000000004 RBP: 00000000004bfcc4 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 000000000056bf80 R13: 00007ffcc552e1bf R14: 00007f15a90dc300 R15: 0000000000022000 Showing all locks held in the system: 1 lock held by khungtaskd/1610: #0: ffffffff8c717ec0 (rcu_read_lock){....}-{1:2}, at: rcu_lock_acquire+0x0/0x30 arch/x86/pci/mmconfig_64.c:151 1 lock held by in:imklog/8130: #0: ffff888035998870 (&f->f_pos_lock){+.+.}-{3:3}, at: __fdget_pos+0x24e/0x2f0 fs/file.c:974 ============================================= NMI backtrace for cpu 1 CPU: 1 PID: 1610 Comm: khungtaskd Not tainted 5.14.0-rc7-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1d3/0x29f lib/dump_stack.c:105 nmi_cpu_backtrace+0x16c/0x190 lib/nmi_backtrace.c:105 nmi_trigger_cpumask_backtrace+0x191/0x2f0 lib/nmi_backtrace.c:62 trigger_all_cpu_backtrace include/linux/nmi.h:146 [inline] check_hung_uninterruptible_tasks kernel/hung_task.c:210 [inline] watchdog+0xd06/0xd50 kernel/hung_task.c:295 kthread+0x453/0x480 kernel/kthread.c:319 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295 Sending NMI from CPU 1 to CPUs 0: NMI backtrace for cpu 0 CPU: 0 PID: 10 Comm: kworker/u4:1 Not tainted 5.14.0-rc7-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: bat_events batadv_nc_worker RIP: 0010:lock_is_held_type+0x1/0x180 kernel/locking/lockdep.c:5653 Code: 74 df 83 3d d8 22 e1 03 00 75 d6 48 c7 c7 80 c3 2e 8a 48 c7 c6 c0 c3 2e 8a 31 c0 e8 c9 8d 72 f7 0f 0b eb bd e8 90 fd ff ff 55 <41> 57 41 56 41 55 41 54 53 48 83 ec 10 65 48 8b 04 25 28 00 00 00 RSP: 0018:ffffc90000cf7990 EFLAGS: 00000202 RAX: 1ffffffff18e3801 RBX: 1ffff9200019ef34 RCX: 0000000080000001 RDX: 0000000000000000 RSI: 00000000ffffffff RDI: ffffffff8c717e20 RBP: ffffc90000cf7a28 R08: dffffc0000000000 R09: fffffbfff1b74ee6 R10: fffffbfff1b74ee6 R11: 0000000000000000 R12: dffffc0000000000 R13: 1ffff9200019ef58 R14: dffffc0000000000 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff8880b9c00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f0a1e997000 CR3: 000000000c48e000 CR4: 00000000001506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: lock_is_held include/linux/lockdep.h:283 [inline] rcu_read_lock_sched_held+0x87/0x110 kernel/rcu/update.c:125 trace_lock_acquire+0x59/0x190 include/trace/events/lock.h:13 lock_acquire+0xa4/0x4a0 kernel/locking/lockdep.c:5596 rcu_lock_acquire+0x2a/0x30 include/linux/rcupdate.h:267 rcu_read_lock include/linux/rcupdate.h:687 [inline] batadv_nc_purge_orig_hash net/batman-adv/network-coding.c:404 [inline] batadv_nc_worker+0xc8/0x5b0 net/batman-adv/network-coding.c:715 process_one_work+0x833/0x10c0 kernel/workqueue.c:2276 worker_thread+0xac1/0x1320 kernel/workqueue.c:2422 kthread+0x453/0x480 kernel/kthread.c:319 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295 ---------------- Code disassembly (best guess): 0: 74 df je 0xffffffe1 2: 83 3d d8 22 e1 03 00 cmpl $0x0,0x3e122d8(%rip) # 0x3e122e1 9: 75 d6 jne 0xffffffe1 b: 48 c7 c7 80 c3 2e 8a mov $0xffffffff8a2ec380,%rdi 12: 48 c7 c6 c0 c3 2e 8a mov $0xffffffff8a2ec3c0,%rsi 19: 31 c0 xor %eax,%eax 1b: e8 c9 8d 72 f7 callq 0xf7728de9 20: 0f 0b ud2 22: eb bd jmp 0xffffffe1 24: e8 90 fd ff ff callq 0xfffffdb9 29: 55 push %rbp * 2a: 41 57 push %r15 <-- trapping instruction 2c: 41 56 push %r14 2e: 41 55 push %r13 30: 41 54 push %r12 32: 53 push %rbx 33: 48 83 ec 10 sub $0x10,%rsp 37: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax 3e: 00 00 --- This report is generated by a bot. It may contain errors. See https://goo.gl/tpsmEJ for more information about syzbot. syzbot engineers can be reached at syzkaller@googlegroups.com. syzbot will keep track of this issue. See: https://goo.gl/tpsmEJ#status for how to communicate with syzbot. For information about bisection process see: https://goo.gl/tpsmEJ#bisection syzbot can test patches for this issue, for details see: https://goo.gl/tpsmEJ#testing-patches ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [syzbot] INFO: task hung in do_proc_bulk 2021-08-28 15:52 [syzbot] INFO: task hung in do_proc_bulk syzbot @ 2021-08-28 18:03 ` Alan Stern 2021-08-28 20:05 ` syzbot 2021-09-02 20:04 ` [syzbot] INFO: task hung in do_proc_bulk Alan Stern 1 sibling, 1 reply; 17+ messages in thread From: Alan Stern @ 2021-08-28 18:03 UTC (permalink / raw) To: syzbot Cc: gregkh, johan, linux-kernel, linux-usb, mathias.nyman, syzkaller-bugs On Sat, Aug 28, 2021 at 08:52:17AM -0700, syzbot wrote: > Hello, > > syzbot found the following issue on: > > HEAD commit: d5ae8d7f85b7 Revert "media: dvb header files: move some he.. > git tree: upstream > console output: https://syzkaller.appspot.com/x/log.txt?x=155fa21e300000 > kernel config: https://syzkaller.appspot.com/x/.config?x=2fd902af77ff1e56 > dashboard link: https://syzkaller.appspot.com/bug?extid=ada0f7d3d9fd2016d927 > compiler: Debian clang version 11.0.1-2, GNU ld (GNU Binutils for Debian) 2.35.1 > syz repro: https://syzkaller.appspot.com/x/repro.syz?x=11a1ab0e300000 > > Bisection is inconclusive: the issue happens on the oldest tested release. > > bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=15662ee1300000 > final oops: https://syzkaller.appspot.com/x/report.txt?x=17662ee1300000 > console output: https://syzkaller.appspot.com/x/log.txt?x=13662ee1300000 > > IMPORTANT: if you fix the issue, please add the following tag to the commit: > Reported-by: syzbot+ada0f7d3d9fd2016d927@syzkaller.appspotmail.com > > INFO: task syz-executor.0:8700 blocked for more than 143 seconds. > Not tainted 5.14.0-rc7-syzkaller #0 > "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. > task:syz-executor.0 state:D stack:23192 pid: 8700 ppid: 8455 flags:0x00004004 > Call Trace: > context_switch kernel/sched/core.c:4681 [inline] > __schedule+0xc07/0x11f0 kernel/sched/core.c:5938 > schedule+0x14b/0x210 kernel/sched/core.c:6017 > schedule_timeout+0x98/0x2f0 kernel/time/timer.c:1857 > do_wait_for_common+0x2da/0x480 kernel/sched/completion.c:85 > __wait_for_common kernel/sched/completion.c:106 [inline] > wait_for_common kernel/sched/completion.c:117 [inline] > wait_for_completion_timeout+0x46/0x60 kernel/sched/completion.c:157 > usb_start_wait_urb+0x167/0x550 drivers/usb/core/message.c:63 > do_proc_bulk+0x978/0x1080 drivers/usb/core/devio.c:1236 Looks like the wait needs to be interruptible. Alan Stern #syz test: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git d5ae8d7f85b7 Index: usb-devel/drivers/usb/core/message.c =================================================================== --- usb-devel.orig/drivers/usb/core/message.c +++ usb-devel/drivers/usb/core/message.c @@ -60,12 +60,18 @@ static int usb_start_wait_urb(struct urb goto out; expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; - if (!wait_for_completion_timeout(&ctx.done, expire)) { + retval = wait_for_completion_interruptible_timeout(&ctx.done, expire); + if (retval <= 0) { usb_kill_urb(urb); - retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); + if (retval < 0) + retval = -EINTR; + else if (ctx.status == -ENOENT) + retval = -ETIMEDOUT; + else + retval = ctx.status; dev_dbg(&urb->dev->dev, - "%s timed out on ep%d%s len=%u/%u\n", + "%s timed out or interrupted on ep%d%s len=%u/%u\n", current->comm, usb_endpoint_num(&urb->ep->desc), usb_urb_dir_in(urb) ? "in" : "out", ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [syzbot] INFO: task hung in do_proc_bulk 2021-08-28 18:03 ` Alan Stern @ 2021-08-28 20:05 ` syzbot 2021-08-29 1:58 ` [PATCH] USB: core: Make usb_start_wait_urb() interruptible Alan Stern 0 siblings, 1 reply; 17+ messages in thread From: syzbot @ 2021-08-28 20:05 UTC (permalink / raw) To: gregkh, johan, linux-kernel, linux-usb, mathias.nyman, stern, syzkaller-bugs Hello, syzbot has tested the proposed patch and the reproducer did not trigger any issue: Reported-and-tested-by: syzbot+ada0f7d3d9fd2016d927@syzkaller.appspotmail.com Tested on: commit: d5ae8d7f Revert "media: dvb header files: move some he.. git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git kernel config: https://syzkaller.appspot.com/x/.config?x=2fd902af77ff1e56 dashboard link: https://syzkaller.appspot.com/bug?extid=ada0f7d3d9fd2016d927 compiler: Debian clang version 11.0.1-2, GNU ld (GNU Binutils for Debian) 2.35.1 patch: https://syzkaller.appspot.com/x/patch.diff?x=16c2799d300000 Note: testing is done by a robot and is best-effort only. ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH] USB: core: Make usb_start_wait_urb() interruptible 2021-08-28 20:05 ` syzbot @ 2021-08-29 1:58 ` Alan Stern 2021-08-30 7:56 ` Johan Hovold 0 siblings, 1 reply; 17+ messages in thread From: Alan Stern @ 2021-08-29 1:58 UTC (permalink / raw) To: Greg KH; +Cc: syzbot, syzkaller-bugs, USB mailing list usb_start_wait_urb() can be called from user processes by means of the USBDEVFS_BULK and USBDEVFS_CONTROL ioctls in usbfs. Consequently it should not contain an uninterruptible wait of arbitrarily long length (the timeout value is specified here by the user, so it can be practically anything). Doing so leads the kernel to complain about "Task X blocked for more than N seconds", as found in testing by syzbot: INFO: task syz-executor.0:8700 blocked for more than 143 seconds. Not tainted 5.14.0-rc7-syzkaller #0 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:syz-executor.0 state:D stack:23192 pid: 8700 ppid: 8455 flags:0x00004004 Call Trace: context_switch kernel/sched/core.c:4681 [inline] __schedule+0xc07/0x11f0 kernel/sched/core.c:5938 schedule+0x14b/0x210 kernel/sched/core.c:6017 schedule_timeout+0x98/0x2f0 kernel/time/timer.c:1857 do_wait_for_common+0x2da/0x480 kernel/sched/completion.c:85 __wait_for_common kernel/sched/completion.c:106 [inline] wait_for_common kernel/sched/completion.c:117 [inline] wait_for_completion_timeout+0x46/0x60 kernel/sched/completion.c:157 usb_start_wait_urb+0x167/0x550 drivers/usb/core/message.c:63 do_proc_bulk+0x978/0x1080 drivers/usb/core/devio.c:1236 proc_bulk drivers/usb/core/devio.c:1273 [inline] usbdev_do_ioctl drivers/usb/core/devio.c:2547 [inline] usbdev_ioctl+0x3441/0x6b10 drivers/usb/core/devio.c:2713 ... This patch fixes the problem by converting the uninterruptible wait to an interruptible one. For the most part this won't affect calls to usb_start_wait_urb(), because they are made by kernel threads and so can't receive most signals. But in some cases such calls may occur in user threads in contexts other than usbfs ioctls. A signal in these circumstances could cause a USB transfer to fail when otherwise it wouldn't. The outcome wouldn't be too dreadful, since USB transfers can fail at any time and the system is prepared to handle these failures gracefully. In theory, for example, a signal might cause a driver's probe routine to fail; in practice if the user doesn't want a probe to fail then he shouldn't send interrupt signals to the probing process. Overall, then, making these delays interruptible seems to be an acceptable risk. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Reported-and-tested-by: syzbot+ada0f7d3d9fd2016d927@syzkaller.appspotmail.com CC: stable@vger.kernel.org --- [as1964] drivers/usb/core/message.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) Index: usb-devel/drivers/usb/core/message.c =================================================================== --- usb-devel.orig/drivers/usb/core/message.c +++ usb-devel/drivers/usb/core/message.c @@ -60,12 +60,18 @@ static int usb_start_wait_urb(struct urb goto out; expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; - if (!wait_for_completion_timeout(&ctx.done, expire)) { + retval = wait_for_completion_interruptible_timeout(&ctx.done, expire); + if (retval <= 0) { usb_kill_urb(urb); - retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); + if (ctx.status != -ENOENT) /* URB already completed */ + retval = ctx.status; + else if (retval == 0) + retval = -ETIMEDOUT; + else + retval = -EINTR; dev_dbg(&urb->dev->dev, - "%s timed out on ep%d%s len=%u/%u\n", + "%s timed out or interrupted on ep%d%s len=%u/%u\n", current->comm, usb_endpoint_num(&urb->ep->desc), usb_urb_dir_in(urb) ? "in" : "out", ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] USB: core: Make usb_start_wait_urb() interruptible 2021-08-29 1:58 ` [PATCH] USB: core: Make usb_start_wait_urb() interruptible Alan Stern @ 2021-08-30 7:56 ` Johan Hovold 2021-08-30 14:46 ` Alan Stern 0 siblings, 1 reply; 17+ messages in thread From: Johan Hovold @ 2021-08-30 7:56 UTC (permalink / raw) To: Alan Stern; +Cc: Greg KH, syzbot, syzkaller-bugs, USB mailing list On Sat, Aug 28, 2021 at 09:58:25PM -0400, Alan Stern wrote: > usb_start_wait_urb() can be called from user processes by means of the > USBDEVFS_BULK and USBDEVFS_CONTROL ioctls in usbfs. Consequently it > should not contain an uninterruptible wait of arbitrarily long length > (the timeout value is specified here by the user, so it can be > practically anything). Doing so leads the kernel to complain about > "Task X blocked for more than N seconds", as found in testing by > syzbot: > > INFO: task syz-executor.0:8700 blocked for more than 143 seconds. > Not tainted 5.14.0-rc7-syzkaller #0 > "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. > task:syz-executor.0 state:D stack:23192 pid: 8700 ppid: 8455 flags:0x00004004 > Call Trace: > context_switch kernel/sched/core.c:4681 [inline] > __schedule+0xc07/0x11f0 kernel/sched/core.c:5938 > schedule+0x14b/0x210 kernel/sched/core.c:6017 > schedule_timeout+0x98/0x2f0 kernel/time/timer.c:1857 > do_wait_for_common+0x2da/0x480 kernel/sched/completion.c:85 > __wait_for_common kernel/sched/completion.c:106 [inline] > wait_for_common kernel/sched/completion.c:117 [inline] > wait_for_completion_timeout+0x46/0x60 kernel/sched/completion.c:157 > usb_start_wait_urb+0x167/0x550 drivers/usb/core/message.c:63 > do_proc_bulk+0x978/0x1080 drivers/usb/core/devio.c:1236 > proc_bulk drivers/usb/core/devio.c:1273 [inline] > usbdev_do_ioctl drivers/usb/core/devio.c:2547 [inline] > usbdev_ioctl+0x3441/0x6b10 drivers/usb/core/devio.c:2713 > ... > > This patch fixes the problem by converting the uninterruptible wait to > an interruptible one. For the most part this won't affect calls to > usb_start_wait_urb(), because they are made by kernel threads and so > can't receive most signals. > > But in some cases such calls may occur in user threads in contexts > other than usbfs ioctls. A signal in these circumstances could cause > a USB transfer to fail when otherwise it wouldn't. The outcome > wouldn't be too dreadful, since USB transfers can fail at any time and > the system is prepared to handle these failures gracefully. In > theory, for example, a signal might cause a driver's probe routine to > fail; in practice if the user doesn't want a probe to fail then he > shouldn't send interrupt signals to the probing process. While probe() triggered through sysfs or by module loading is one example, the USB msg helpers are also called in a lot of other user-thread contexts such as open() calls etc. It might even be that the majority of these calls can be done from user threads (post enumeration). > Overall, then, making these delays interruptible seems to be an > acceptable risk. Possibly, but changing the API like this to fix the usbfs ioctls seems like using a bit of a too big hammer to me, especially when backporting to stable. > Signed-off-by: Alan Stern <stern@rowland.harvard.edu> > Reported-and-tested-by: syzbot+ada0f7d3d9fd2016d927@syzkaller.appspotmail.com > CC: stable@vger.kernel.org Johan ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] USB: core: Make usb_start_wait_urb() interruptible 2021-08-30 7:56 ` Johan Hovold @ 2021-08-30 14:46 ` Alan Stern 2021-08-30 15:11 ` Oliver Neukum 2021-08-31 9:13 ` Johan Hovold 0 siblings, 2 replies; 17+ messages in thread From: Alan Stern @ 2021-08-30 14:46 UTC (permalink / raw) To: Johan Hovold; +Cc: Greg KH, syzbot, syzkaller-bugs, USB mailing list On Mon, Aug 30, 2021 at 09:56:50AM +0200, Johan Hovold wrote: > On Sat, Aug 28, 2021 at 09:58:25PM -0400, Alan Stern wrote: > > This patch fixes the problem by converting the uninterruptible wait to > > an interruptible one. For the most part this won't affect calls to > > usb_start_wait_urb(), because they are made by kernel threads and so > > can't receive most signals. > > > > But in some cases such calls may occur in user threads in contexts > > other than usbfs ioctls. A signal in these circumstances could cause > > a USB transfer to fail when otherwise it wouldn't. The outcome > > wouldn't be too dreadful, since USB transfers can fail at any time and > > the system is prepared to handle these failures gracefully. In > > theory, for example, a signal might cause a driver's probe routine to > > fail; in practice if the user doesn't want a probe to fail then he > > shouldn't send interrupt signals to the probing process. > > While probe() triggered through sysfs or by module loading is one > example, the USB msg helpers are also called in a lot of other > user-thread contexts such as open() calls etc. It might even be that the > majority of these calls can be done from user threads (post > enumeration). Could be. It's not a well defined matter; it depends on what drivers are in use and how they are used. Consider that a control message in a driver is likely to use the default USB_CTRL_[GS]ET_TIMEOUT value of 5 seconds. Does it make sense to allow uninterruptible wait states to last as long as that? And to what extent does it matter if we make these delays interruptible? A signal delivered during a system call will be fielded when the call returns if not earlier; the only difference will be that now some USB messages may be aborted. For things like SIGINT or SIGTERM this seems reasonable. (I'm not so sure about things like SIGALRM, SIGIO, or SIGSTOP, though.) > > Overall, then, making these delays interruptible seems to be an > > acceptable risk. > > Possibly, but changing the API like this to fix the usbfs ioctls seems > like using a bit of a too big hammer to me, especially when backporting > to stable. Perhaps the stable backport could be delayed for a while (say, one release cycle). Do you have alternative suggestions? I don't think we want special interruptible versions of usb_control_msg() and usb_bulk_msg() just for use by usbfs. Alan Stern ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] USB: core: Make usb_start_wait_urb() interruptible 2021-08-30 14:46 ` Alan Stern @ 2021-08-30 15:11 ` Oliver Neukum 2021-08-30 16:09 ` Alan Stern 2021-08-31 9:13 ` Johan Hovold 1 sibling, 1 reply; 17+ messages in thread From: Oliver Neukum @ 2021-08-30 15:11 UTC (permalink / raw) To: Alan Stern, Johan Hovold Cc: Greg KH, syzbot, syzkaller-bugs, USB mailing list On 30.08.21 16:46, Alan Stern wrote: > Do you have alternative suggestions? I don't think we want special > interruptible versions of usb_control_msg() and usb_bulk_msg() just for > use by usbfs. Hi, why not just pass a flag? Regards Oliver ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] USB: core: Make usb_start_wait_urb() interruptible 2021-08-30 15:11 ` Oliver Neukum @ 2021-08-30 16:09 ` Alan Stern 2021-08-31 8:52 ` Oliver Neukum 0 siblings, 1 reply; 17+ messages in thread From: Alan Stern @ 2021-08-30 16:09 UTC (permalink / raw) To: Oliver Neukum Cc: Johan Hovold, Greg KH, syzbot, syzkaller-bugs, USB mailing list On Mon, Aug 30, 2021 at 05:11:53PM +0200, Oliver Neukum wrote: > > On 30.08.21 16:46, Alan Stern wrote: > > Do you have alternative suggestions? I don't think we want special > > interruptible versions of usb_control_msg() and usb_bulk_msg() just for > > use by usbfs. > > Hi, > > why not just pass a flag? We could. But you're ignoring the question I asked earlier in that email: Is a 5-second uninterruptible delay (the default USB control timeout) acceptable in general? Alan Stern ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] USB: core: Make usb_start_wait_urb() interruptible 2021-08-30 16:09 ` Alan Stern @ 2021-08-31 8:52 ` Oliver Neukum 0 siblings, 0 replies; 17+ messages in thread From: Oliver Neukum @ 2021-08-31 8:52 UTC (permalink / raw) To: Alan Stern Cc: Johan Hovold, Greg KH, syzbot, syzkaller-bugs, USB mailing list On 30.08.21 18:09, Alan Stern wrote: > On Mon, Aug 30, 2021 at 05:11:53PM +0200, Oliver Neukum wrote: >> On 30.08.21 16:46, Alan Stern wrote: >>> Do you have alternative suggestions? I don't think we want special >>> interruptible versions of usb_control_msg() and usb_bulk_msg() just for >>> use by usbfs. >> Hi, >> >> why not just pass a flag? > We could. But you're ignoring the question I asked earlier in that > email: Is a 5-second uninterruptible delay (the default USB control > timeout) acceptable in general? We cannot change the five seconds, so this boils down to whether we can always handle signals when we need to send control messages. The answer to that is negative. Suspend/resume, block IO, probe, ioctl(). This list will be rather long. Regards Oliver ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] USB: core: Make usb_start_wait_urb() interruptible 2021-08-30 14:46 ` Alan Stern 2021-08-30 15:11 ` Oliver Neukum @ 2021-08-31 9:13 ` Johan Hovold 2021-08-31 10:47 ` Oliver Neukum ` (2 more replies) 1 sibling, 3 replies; 17+ messages in thread From: Johan Hovold @ 2021-08-31 9:13 UTC (permalink / raw) To: Alan Stern; +Cc: Greg KH, syzbot, syzkaller-bugs, USB mailing list On Mon, Aug 30, 2021 at 10:46:13AM -0400, Alan Stern wrote: > On Mon, Aug 30, 2021 at 09:56:50AM +0200, Johan Hovold wrote: > > On Sat, Aug 28, 2021 at 09:58:25PM -0400, Alan Stern wrote: > > > This patch fixes the problem by converting the uninterruptible wait to > > > an interruptible one. For the most part this won't affect calls to > > > usb_start_wait_urb(), because they are made by kernel threads and so > > > can't receive most signals. > > > > > > But in some cases such calls may occur in user threads in contexts > > > other than usbfs ioctls. A signal in these circumstances could cause > > > a USB transfer to fail when otherwise it wouldn't. The outcome > > > wouldn't be too dreadful, since USB transfers can fail at any time and > > > the system is prepared to handle these failures gracefully. In > > > theory, for example, a signal might cause a driver's probe routine to > > > fail; in practice if the user doesn't want a probe to fail then he > > > shouldn't send interrupt signals to the probing process. > > > > While probe() triggered through sysfs or by module loading is one > > example, the USB msg helpers are also called in a lot of other > > user-thread contexts such as open() calls etc. It might even be that the > > majority of these calls can be done from user threads (post > > enumeration). > > Could be. It's not a well defined matter; it depends on what drivers > are in use and how they are used. Right, but the commit message seemed to suggest that these helpers being run from interruptible threads was the exception. > Consider that a control message in a driver is likely to use the > default USB_CTRL_[GS]ET_TIMEOUT value of 5 seconds. Does it make sense > to allow uninterruptible wait states to last as long as that? Perhaps sometimes? I don't have a use case at hand, but I haven't reviewed all drivers either. The comment above usb_start_wait_urb() (which also needs to be updated, by the way) even suggests that drivers should "implement their own interruptible routines" so perhaps this has just gone unnoticed for 20 odd years. And the question then becomes, why didn't we use interruptible sleep from the start? And trying to answer that I find that that's precisely what we did, but for some reason it was changed to uninterruptible sleep in v2.4.11 without a motivation (that I could easily find spelled out). > And to what extent does it matter if we make these delays > interruptible? A signal delivered during a system call will be fielded > when the call returns if not earlier; the only difference will be that > now some USB messages may be aborted. For things like SIGINT or > SIGTERM this seems reasonable. (I'm not so sure about things like > SIGALRM, SIGIO, or SIGSTOP, though.) I'm not saying I'm necessarily against the change. It just seemed a bit rushed to change the (stable) API like this while claiming it won't affect most call sites. > > > Overall, then, making these delays interruptible seems to be an > > > acceptable risk. > > > > Possibly, but changing the API like this to fix the usbfs ioctls seems > > like using a bit of a too big hammer to me, especially when backporting > > to stable. > > Perhaps the stable backport could be delayed for a while (say, one > release cycle). That might work. > Do you have alternative suggestions? I don't think we want special > interruptible versions of usb_control_msg() and usb_bulk_msg() just for > use by usbfs. usbfs could carry a temporary local implementation as the documentation for usb_start_wait_urb() currently suggests. I assume we can't limit the usbfs timeouts. Johan ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] USB: core: Make usb_start_wait_urb() interruptible 2021-08-31 9:13 ` Johan Hovold @ 2021-08-31 10:47 ` Oliver Neukum 2021-08-31 11:02 ` Oliver Neukum 2021-08-31 11:10 ` Johan Hovold 2 siblings, 0 replies; 17+ messages in thread From: Oliver Neukum @ 2021-08-31 10:47 UTC (permalink / raw) To: Johan Hovold, Alan Stern Cc: Greg KH, syzbot, syzkaller-bugs, USB mailing list On 31.08.21 11:13, Johan Hovold wrote: > The comment above usb_start_wait_urb() (which also needs to be updated, > by the way) even suggests that drivers should "implement their own > interruptible routines" so perhaps this has just gone unnoticed for 20 > odd years. And the question then becomes, why didn't we use > interruptible sleep from the start? > > And trying to answer that I find that that's precisely what we did, but > for some reason it was changed to uninterruptible sleep in v2.4.11 > without a motivation (that I could easily find spelled out). I must admit that I do not remember. But there are a lot of situations requiring control messages that do not allow signal delivery. Take for example a device that is HID and storage. We are doing HID error handling, which can involve a device reset. You absolutely cannot deliver a signal right now, as you have a device that is in an undefined state in the block layer. It looks to me very much like we need both versions and as a rule of thumb, while you would use GFP_NOIO you must also use the uninterruptible messaging. Regards Oliver ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] USB: core: Make usb_start_wait_urb() interruptible 2021-08-31 9:13 ` Johan Hovold 2021-08-31 10:47 ` Oliver Neukum @ 2021-08-31 11:02 ` Oliver Neukum 2021-08-31 11:10 ` Johan Hovold 2 siblings, 0 replies; 17+ messages in thread From: Oliver Neukum @ 2021-08-31 11:02 UTC (permalink / raw) To: Johan Hovold, Alan Stern Cc: Greg KH, syzbot, syzkaller-bugs, USB mailing list On 31.08.21 11:13, Johan Hovold wrote: > On Mon, Aug 30, 2021 at 10:46:13AM -0400, Alan Stern wrote: >> Perhaps the stable backport could be delayed for a while (say, one >> release cycle). > That might work. > >> Do you have alternative suggestions? I don't think we want special >> interruptible versions of usb_control_msg() and usb_bulk_msg() just for >> use by usbfs. > usbfs could carry a temporary local implementation as the documentation > for usb_start_wait_urb() currently suggests. I assume we can't limit the > usbfs timeouts. Upon further considerations forcing user space to handle signals also breaks the API, albeit in a more subtle manner. I'd suggest that we use wait_event_killable_timeout(). And do it the way Alan initially disliked, that is code a version for use by usbfs. Thus we'd avoid the issue of having an unkillable process, but we do not impose a need to handle signals. Regards Oliver ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] USB: core: Make usb_start_wait_urb() interruptible 2021-08-31 9:13 ` Johan Hovold 2021-08-31 10:47 ` Oliver Neukum 2021-08-31 11:02 ` Oliver Neukum @ 2021-08-31 11:10 ` Johan Hovold 2021-08-31 17:03 ` Alan Stern 2 siblings, 1 reply; 17+ messages in thread From: Johan Hovold @ 2021-08-31 11:10 UTC (permalink / raw) To: Alan Stern; +Cc: Greg KH, syzbot, syzkaller-bugs, USB mailing list On Tue, Aug 31, 2021 at 11:13:59AM +0200, Johan Hovold wrote: > On Mon, Aug 30, 2021 at 10:46:13AM -0400, Alan Stern wrote: > > Consider that a control message in a driver is likely to use the > > default USB_CTRL_[GS]ET_TIMEOUT value of 5 seconds. Does it make sense > > to allow uninterruptible wait states to last as long as that? > > Perhaps sometimes? I don't have a use case at hand, but I haven't > reviewed all drivers either. > > The comment above usb_start_wait_urb() (which also needs to be updated, > by the way) even suggests that drivers should "implement their own > interruptible routines" so perhaps this has just gone unnoticed for 20 > odd years. And the question then becomes, why didn't we use > interruptible sleep from the start? > > And trying to answer that I find that that's precisely what we did, but > for some reason it was changed to uninterruptible sleep in v2.4.11 > without a motivation (that I could easily find spelled out). Here it is: https://lore.kernel.org/lkml/20010818013101.A7058@devserv.devel.redhat.com/ It's rationale does not seem valid anymore (i.e. the NULL deref), but the example is still instructive. If you close for example a v4l application you still expect the device to be shut down orderly but with interruptible sleep all control requests during shutdown will be aborted immediately. Similar for USB serial devices which would for example fail to deassert DTR/RTS, etc. (I just verified with the patch applied.) Johan ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] USB: core: Make usb_start_wait_urb() interruptible 2021-08-31 11:10 ` Johan Hovold @ 2021-08-31 17:03 ` Alan Stern 2021-09-01 8:16 ` Oliver Neukum 0 siblings, 1 reply; 17+ messages in thread From: Alan Stern @ 2021-08-31 17:03 UTC (permalink / raw) To: Johan Hovold, Oliver Neukum Cc: Greg KH, syzbot, syzkaller-bugs, USB mailing list On Tue, Aug 31, 2021 at 01:10:32PM +0200, Johan Hovold wrote: > On Tue, Aug 31, 2021 at 11:13:59AM +0200, Johan Hovold wrote: > > On Mon, Aug 30, 2021 at 10:46:13AM -0400, Alan Stern wrote: > > > > Consider that a control message in a driver is likely to use the > > > default USB_CTRL_[GS]ET_TIMEOUT value of 5 seconds. Does it make sense > > > to allow uninterruptible wait states to last as long as that? > > > > Perhaps sometimes? I don't have a use case at hand, but I haven't > > reviewed all drivers either. > > > > The comment above usb_start_wait_urb() (which also needs to be updated, > > by the way) even suggests that drivers should "implement their own > > interruptible routines" so perhaps this has just gone unnoticed for 20 > > odd years. And the question then becomes, why didn't we use > > interruptible sleep from the start? > > > > And trying to answer that I find that that's precisely what we did, but > > for some reason it was changed to uninterruptible sleep in v2.4.11 > > without a motivation (that I could easily find spelled out). > > Here it is: > > https://lore.kernel.org/lkml/20010818013101.A7058@devserv.devel.redhat.com/ > > It's rationale does not seem valid anymore (i.e. the NULL deref), but > the example is still instructive. > > If you close for example a v4l application you still expect the device > to be shut down orderly but with interruptible sleep all control > requests during shutdown will be aborted immediately. > > Similar for USB serial devices which would for example fail to deassert > DTR/RTS, etc. (I just verified with the patch applied.) On Tue, Aug 31, 2021 at 01:02:11PM +0200, Oliver Neukum wrote: > Upon further considerations forcing user space to handle signals also > breaks the API, albeit in a more subtle manner. I'd suggest that we use > wait_event_killable_timeout(). And do it the way Alan initially disliked, > that is code a version for use by usbfs. > > Thus we'd avoid the issue of having an unkillable process, but we do > not impose a need to handle signals. Okay, I'll play it safe and rewrite the patch, adding special-purpose routines just for usbfs. Will wait_event_killable_timeout() prevent complaints about tasks being blocked for too long (the reason syzbot reported this in the first place)? Alan Stern ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] USB: core: Make usb_start_wait_urb() interruptible 2021-08-31 17:03 ` Alan Stern @ 2021-09-01 8:16 ` Oliver Neukum 0 siblings, 0 replies; 17+ messages in thread From: Oliver Neukum @ 2021-09-01 8:16 UTC (permalink / raw) To: Alan Stern, Johan Hovold Cc: Greg KH, syzbot, syzkaller-bugs, USB mailing list On 31.08.21 19:03, Alan Stern wrote: > > Will wait_event_killable_timeout() prevent complaints about tasks being > blocked for too long (the reason syzbot reported this in the first > place)? Very good question. TASK_KILLABLE is its own task state, so I'd say if it doesn't the test suite needs to be fixed. Regards Oliver ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [syzbot] INFO: task hung in do_proc_bulk 2021-08-28 15:52 [syzbot] INFO: task hung in do_proc_bulk syzbot 2021-08-28 18:03 ` Alan Stern @ 2021-09-02 20:04 ` Alan Stern 2021-09-02 20:46 ` syzbot 1 sibling, 1 reply; 17+ messages in thread From: Alan Stern @ 2021-09-02 20:04 UTC (permalink / raw) To: syzbot; +Cc: linux-kernel, linux-usb, syzkaller-bugs Let's see if making the wait killable rather than interruptible fixes the issue. This patch avoids modifying the regular usb_start_wait_urb(), creating a separate usbfs_start_wait_urb() just for this purpose. Alan Stern #syz test: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git d5ae8d7f85b7 Index: usb-devel/drivers/usb/core/devio.c =================================================================== --- usb-devel.orig/drivers/usb/core/devio.c +++ usb-devel/drivers/usb/core/devio.c @@ -32,6 +32,7 @@ #include <linux/usb.h> #include <linux/usbdevice_fs.h> #include <linux/usb/hcd.h> /* for usbcore internals */ +#include <linux/usb/quirks.h> #include <linux/cdev.h> #include <linux/notifier.h> #include <linux/security.h> @@ -1102,14 +1103,55 @@ static int usbdev_release(struct inode * return 0; } +static void usbfs_blocking_completion(struct urb *urb) +{ + complete((struct completion *) urb->context); +} + +/* + * Much like usb_start_wait_urb, but returns status separately from + * actual_length and uses a killable wait. + */ +static int usbfs_start_wait_urb(struct urb *urb, int timeout, + unsigned int *actlen) +{ + DECLARE_COMPLETION_ONSTACK(ctx); + unsigned long expire; + int rc; + + urb->context = &ctx; + urb->complete = usbfs_blocking_completion; + *actlen = 0; + rc = usb_submit_urb(urb, GFP_KERNEL); + if (unlikely(rc)) + return rc; + + expire = (timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT); + rc = wait_for_completion_killable_timeout(&ctx, expire); + if (rc <= 0) { + usb_kill_urb(urb); + *actlen = urb->actual_length; + if (urb->status != -ENOENT) + ; /* Completed before it was killed */ + else if (rc < 0) + return -EINTR; + else + return -ETIMEDOUT; + } + *actlen = urb->actual_length; + return urb->status; +} + static int do_proc_control(struct usb_dev_state *ps, struct usbdevfs_ctrltransfer *ctrl) { struct usb_device *dev = ps->dev; unsigned int tmo; unsigned char *tbuf; - unsigned wLength; + unsigned wLength, actlen; int i, pipe, ret; + struct urb *urb = NULL; + struct usb_ctrlrequest *dr = NULL; ret = check_ctrlrecip(ps, ctrl->bRequestType, ctrl->bRequest, ctrl->wIndex); @@ -1122,51 +1164,63 @@ static int do_proc_control(struct usb_de sizeof(struct usb_ctrlrequest)); if (ret) return ret; + + ret = -ENOMEM; tbuf = (unsigned char *)__get_free_page(GFP_KERNEL); - if (!tbuf) { - ret = -ENOMEM; + if (!tbuf) goto done; - } + urb = usb_alloc_urb(0, GFP_NOIO); + if (!urb) + goto done; + dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); + if (!dr) + goto done; + + dr->bRequestType = ctrl->bRequestType; + dr->bRequest = ctrl->bRequest; + dr->wValue = cpu_to_le16(ctrl->wValue); + dr->wIndex = cpu_to_le16(ctrl->wIndex); + dr->wLength = cpu_to_le16(ctrl->wLength); + tmo = ctrl->timeout; snoop(&dev->dev, "control urb: bRequestType=%02x " "bRequest=%02x wValue=%04x " "wIndex=%04x wLength=%04x\n", ctrl->bRequestType, ctrl->bRequest, ctrl->wValue, ctrl->wIndex, ctrl->wLength); - if ((ctrl->bRequestType & USB_DIR_IN) && ctrl->wLength) { + + if ((ctrl->bRequestType & USB_DIR_IN) && wLength) { pipe = usb_rcvctrlpipe(dev, 0); - snoop_urb(dev, NULL, pipe, ctrl->wLength, tmo, SUBMIT, NULL, 0); + usb_fill_control_urb(urb, dev, pipe, (unsigned char *) dr, tbuf, + wLength, NULL, NULL); + snoop_urb(dev, NULL, pipe, wLength, tmo, SUBMIT, NULL, 0); usb_unlock_device(dev); - i = usb_control_msg(dev, pipe, ctrl->bRequest, - ctrl->bRequestType, ctrl->wValue, ctrl->wIndex, - tbuf, ctrl->wLength, tmo); + i = usbfs_start_wait_urb(urb, tmo, &actlen); usb_lock_device(dev); - snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, - tbuf, max(i, 0)); - if ((i > 0) && ctrl->wLength) { - if (copy_to_user(ctrl->data, tbuf, i)) { + snoop_urb(dev, NULL, pipe, actlen, i, COMPLETE, tbuf, actlen); + if (!i && actlen) { + if (copy_to_user(ctrl->data, tbuf, actlen)) { ret = -EFAULT; - goto done; + goto recv_fault; } } } else { - if (ctrl->wLength) { - if (copy_from_user(tbuf, ctrl->data, ctrl->wLength)) { + if (wLength) { + if (copy_from_user(tbuf, ctrl->data, wLength)) { ret = -EFAULT; goto done; } } pipe = usb_sndctrlpipe(dev, 0); - snoop_urb(dev, NULL, pipe, ctrl->wLength, tmo, SUBMIT, - tbuf, ctrl->wLength); + usb_fill_control_urb(urb, dev, pipe, (unsigned char *) dr, tbuf, + wLength, NULL, NULL); + snoop_urb(dev, NULL, pipe, wLength, tmo, SUBMIT, tbuf, wLength); usb_unlock_device(dev); - i = usb_control_msg(dev, pipe, ctrl->bRequest, - ctrl->bRequestType, ctrl->wValue, ctrl->wIndex, - tbuf, ctrl->wLength, tmo); + i = usbfs_start_wait_urb(urb, tmo, &actlen); usb_lock_device(dev); - snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, NULL, 0); + snoop_urb(dev, NULL, pipe, actlen, i, COMPLETE, NULL, 0); } if (i < 0 && i != -EPIPE) { dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL " @@ -1174,8 +1228,15 @@ static int do_proc_control(struct usb_de current->comm, ctrl->bRequestType, ctrl->bRequest, ctrl->wLength, i); } - ret = i; + ret = (i < 0 ? i : actlen); + + recv_fault: + /* Linger a bit, prior to the next control message. */ + if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG) + msleep(200); done: + kfree(dr); + usb_free_urb(urb); free_page((unsigned long) tbuf); usbfs_decrease_memory_usage(PAGE_SIZE + sizeof(struct urb) + sizeof(struct usb_ctrlrequest)); @@ -1195,10 +1256,11 @@ static int do_proc_bulk(struct usb_dev_s struct usbdevfs_bulktransfer *bulk) { struct usb_device *dev = ps->dev; - unsigned int tmo, len1, pipe; - int len2; + unsigned int tmo, len1, len2, pipe; unsigned char *tbuf; int i, ret; + struct urb *urb = NULL; + struct usb_host_endpoint *ep; ret = findintfep(ps->dev, bulk->ep); if (ret < 0) @@ -1206,14 +1268,17 @@ static int do_proc_bulk(struct usb_dev_s ret = checkintf(ps, ret); if (ret) return ret; + + len1 = bulk->len; + if (len1 < 0 || len1 >= (INT_MAX - sizeof(struct urb))) + return -EINVAL; + if (bulk->ep & USB_DIR_IN) pipe = usb_rcvbulkpipe(dev, bulk->ep & 0x7f); else pipe = usb_sndbulkpipe(dev, bulk->ep & 0x7f); - if (!usb_maxpacket(dev, pipe, !(bulk->ep & USB_DIR_IN))) - return -EINVAL; - len1 = bulk->len; - if (len1 >= (INT_MAX - sizeof(struct urb))) + ep = usb_pipe_endpoint(dev, pipe); + if (!ep || !usb_endpoint_maxp(&ep->desc)) return -EINVAL; ret = usbfs_increase_memory_usage(len1 + sizeof(struct urb)); if (ret) @@ -1223,17 +1288,29 @@ static int do_proc_bulk(struct usb_dev_s * len1 can be almost arbitrarily large. Don't WARN if it's * too big, just fail the request. */ + ret = -ENOMEM; tbuf = kmalloc(len1, GFP_KERNEL | __GFP_NOWARN); - if (!tbuf) { - ret = -ENOMEM; + if (!tbuf) goto done; + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) + goto done; + + if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT) { + pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); + usb_fill_int_urb(urb, dev, pipe, tbuf, len1, + NULL, NULL, ep->desc.bInterval); + } else { + usb_fill_bulk_urb(urb, dev, pipe, tbuf, len1, NULL, NULL); } + tmo = bulk->timeout; if (bulk->ep & 0x80) { snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, NULL, 0); usb_unlock_device(dev); - i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); + i = usbfs_start_wait_urb(urb, tmo, &len2); usb_lock_device(dev); snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, tbuf, len2); @@ -1253,12 +1330,13 @@ static int do_proc_bulk(struct usb_dev_s snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, tbuf, len1); usb_unlock_device(dev); - i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo); + i = usbfs_start_wait_urb(urb, tmo, &len2); usb_lock_device(dev); snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, NULL, 0); } ret = (i < 0 ? i : len2); done: + usb_free_urb(urb); kfree(tbuf); usbfs_decrease_memory_usage(len1 + sizeof(struct urb)); return ret; ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [syzbot] INFO: task hung in do_proc_bulk 2021-09-02 20:04 ` [syzbot] INFO: task hung in do_proc_bulk Alan Stern @ 2021-09-02 20:46 ` syzbot 0 siblings, 0 replies; 17+ messages in thread From: syzbot @ 2021-09-02 20:46 UTC (permalink / raw) To: linux-kernel, linux-usb, stern, syzkaller-bugs Hello, syzbot has tested the proposed patch and the reproducer did not trigger any issue: Reported-and-tested-by: syzbot+ada0f7d3d9fd2016d927@syzkaller.appspotmail.com Tested on: commit: d5ae8d7f Revert "media: dvb header files: move some he.. git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git kernel config: https://syzkaller.appspot.com/x/.config?x=2fd902af77ff1e56 dashboard link: https://syzkaller.appspot.com/bug?extid=ada0f7d3d9fd2016d927 compiler: Debian clang version 11.0.1-2, GNU ld (GNU Binutils for Debian) 2.35.1 patch: https://syzkaller.appspot.com/x/patch.diff?x=112280a3300000 Note: testing is done by a robot and is best-effort only. ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2021-09-02 20:46 UTC | newest] Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-08-28 15:52 [syzbot] INFO: task hung in do_proc_bulk syzbot 2021-08-28 18:03 ` Alan Stern 2021-08-28 20:05 ` syzbot 2021-08-29 1:58 ` [PATCH] USB: core: Make usb_start_wait_urb() interruptible Alan Stern 2021-08-30 7:56 ` Johan Hovold 2021-08-30 14:46 ` Alan Stern 2021-08-30 15:11 ` Oliver Neukum 2021-08-30 16:09 ` Alan Stern 2021-08-31 8:52 ` Oliver Neukum 2021-08-31 9:13 ` Johan Hovold 2021-08-31 10:47 ` Oliver Neukum 2021-08-31 11:02 ` Oliver Neukum 2021-08-31 11:10 ` Johan Hovold 2021-08-31 17:03 ` Alan Stern 2021-09-01 8:16 ` Oliver Neukum 2021-09-02 20:04 ` [syzbot] INFO: task hung in do_proc_bulk Alan Stern 2021-09-02 20:46 ` syzbot
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.