Re: INFO: task hung in usb_kill_urb

From: Alan Stern
Date: Tue Apr 16 2019 - 17:14:41 EST


On Tue, 16 Apr 2019, syzbot wrote:

> Hello,
>
> syzbot has tested the proposed patch and the reproducer did not trigger
> crash:

Slight fixup to the patch. Unsupported speeds aren't necessarily
bogus, and what matters is the actual speed rather than the max_speed.
Also, we want to be able to give back unlinked URBs even after a
frame's total bandwidth has been exhausted.

Alan Stern

#syz test: https://github.com/google/kasan.git usb-fuzzer

--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -979,8 +979,18 @@ static int dummy_udc_start(struct usb_ga
struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g);
struct dummy *dum = dum_hcd->dum;

- if (driver->max_speed == USB_SPEED_UNKNOWN)
+ switch (g->speed) {
+ /* All the speeds we support */
+ case USB_SPEED_LOW:
+ case USB_SPEED_FULL:
+ case USB_SPEED_HIGH:
+ case USB_SPEED_SUPER:
+ break;
+ default:
+ dev_err(dummy_dev(dum_hcd), "Unsupported driver max speed %d\n",
+ driver->max_speed);
return -EINVAL;
+ }

/*
* SLAVE side init ... the layer above hardware, which
@@ -1784,7 +1794,7 @@ static void dummy_timer(struct timer_lis
/* Bus speed is 500000 bytes/ms, so use a little less */
total = 490000;
break;
- default:
+ default: /* Can't happen */
dev_err(dummy_dev(dum_hcd), "bogus device speed\n");
return;
}
@@ -1828,7 +1838,7 @@ restart:

/* Used up this frame's bandwidth? */
if (total <= 0)
- break;
+ continue;

/* find the gadget's ep for this request (if configured) */
address = usb_pipeendpoint (urb->pipe);