From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: USB: dummy-hcd: Fix failure to give back unlinked URBs From: Alan Stern Message-Id: Date: Thu, 18 Apr 2019 13:12:07 -0400 (EDT) To: Greg KH Cc: andreyknvl@google.com, gustavo@embeddedor.com, USB list , syzkaller-bugs@googlegroups.com List-ID: VGhlIHN5emthbGxlciBVU0IgZnV6emVyIGlkZW50aWZpZWQgYSBmYWlsdXJlIG1vZGUgaW4gd2hp Y2ggZHVtbXktaGNkCndvdWxkIG5ldmVyIGdpdmUgYmFjayBhbiB1bmxpbmtlZCBVUkIuICBUaGlz IGNhdXNlcyB1c2Jfa2lsbF91cmIoKSB0bwpoYW5nLCBsZWFkaW5nIHRvIFdBUk5JTkdzIGFuZCB1 bmtpbGxhYmxlIHRocmVhZHMuCgpJbiBkdW1teS1oY2QsIGFsbCBVUkJzIGFyZSBnaXZlbiBiYWNr IGJ5IHRoZSBkdW1teV90aW1lcigpIHJvdXRpbmUgYXMKaXQgc2NhbnMgdGhyb3VnaCB0aGUgbGlz dCBvZiBwZW5kaW5nIFVSQlMuICBGYWlsdXJlIHRvIGdpdmUgYmFjayBVUkJzCmNhbiBiZSBjYXVz ZWQgYnkgZmFpbHVyZSB0byBzdGFydCBvciBlYXJseSBleGl0IGZyb20gdGhlIHNjYW5uaW5nCmxv b3AuICBUaGUgY29kZSBjdXJyZW50bHkgaGFzIHR3byBzdWNoIHBhdGh3YXlzOiBPbmUgaXMgdHJp Z2dlcmVkIHdoZW4KYW4gdW5zdXBwb3J0ZWQgYnVzIHRyYW5zZmVyIHNwZWVkIGlzIGVuY291bnRl cmVkLCBhbmQgdGhlIG90aGVyIGJ5CmV4aGF1c3RpbmcgdGhlIHNpbXVsYXRlZCBiYW5kd2lkdGgg Zm9yIFVTQiB0cmFuc2ZlcnMgZHVyaW5nIGEgZnJhbWUuCgpUaGlzIHBhdGNoIHJlbW92ZXMgdGhv c2UgdHdvIHBhdGhzLCB0aGVyZWJ5IGFsbG93aW5nIGFsbCB1bmxpbmtlZCBVUkJzCnRvIGJlIGdp dmVuIGJhY2sgaW4gYSB0aW1lbHkgbWFubmVyLiAgSXQgYWRkcyBhIGNoZWNrIGZvciB0aGUgYnVz CnNwZWVkIHdoZW4gdGhlIGdhZGdldCBmaXJzdCBzdGFydHMgcnVubmluZywgc28gdGhhdCBkdW1t eV90aW1lcigpIHdpbGwKbmV2ZXIgdGhlcmVhZnRlciBlbmNvdW50ZXIgYW4gdW5zdXBwb3J0ZWQg c3BlZWQuICBBbmQgaXQgcHJldmVudHMgdGhlCmxvb3AgZnJvbSBleGl0aW5nIGFzIHNvb24gYXMg dGhlIHRvdGFsIGJhbmR3aWR0aCBoYXMgYmVlbiB1c2VkIHVwICh0aGUKc2Nhbm5pbmcgbG9vcCBj b250aW51ZXMsIGdpdmluZyBiYWNrIHVubGlua2VkIFVSQnMgYXMgdGhleSBhcmUgZm91bmQsCmJ1 dCBub3QgdHJhbnNmZXJyaW5nIGFueSBtb3JlIGRhdGEpLgoKVGhhbmtzIHRvIEFuZHJleSBLb25v dmFsb3YgZm9yIG1hbnVhbGx5IHJ1bm5pbmcgdGhlIHN5emthbGxlciBmdXp6ZXIKdG8gaGVscCB0 cmFjayBkb3duIHRoZSBzb3VyY2Ugb2YgdGhlIGJ1Zy4KClNpZ25lZC1vZmYtYnk6IEFsYW4gU3Rl cm4gPHN0ZXJuQHJvd2xhbmQuaGFydmFyZC5lZHU+ClJlcG9ydGVkLWFuZC10ZXN0ZWQtYnk6IHN5 emJvdCtkOTE5YjBmMjlkN2I1YTQ5OTRiOUBzeXprYWxsZXIuYXBwc3BvdG1haWwuY29tCkNDOiA8 c3RhYmxlQHZnZXIua2VybmVsLm9yZz4KLS0tCgoKW2FzMTg4OV0KCgogZHJpdmVycy91c2IvZ2Fk Z2V0L3VkYy9kdW1teV9oY2QuYyB8ICAgMTkgKysrKysrKysrKysrKysrLS0tLQogMSBmaWxlIGNo YW5nZWQsIDE1IGluc2VydGlvbnMoKyksIDQgZGVsZXRpb25zKC0pCgpJbmRleDogdXNiLWRldmVs L2RyaXZlcnMvdXNiL2dhZGdldC91ZGMvZHVtbXlfaGNkLmMKPT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gdXNiLWRl dmVsLm9yaWcvZHJpdmVycy91c2IvZ2FkZ2V0L3VkYy9kdW1teV9oY2QuYworKysgdXNiLWRldmVs L2RyaXZlcnMvdXNiL2dhZGdldC91ZGMvZHVtbXlfaGNkLmMKQEAgLTk3OSw4ICs5NzksMTggQEAg c3RhdGljIGludCBkdW1teV91ZGNfc3RhcnQoc3RydWN0IHVzYl9nYQogCXN0cnVjdCBkdW1teV9o Y2QJKmR1bV9oY2QgPSBnYWRnZXRfdG9fZHVtbXlfaGNkKGcpOwogCXN0cnVjdCBkdW1teQkJKmR1 bSA9IGR1bV9oY2QtPmR1bTsKIAotCWlmIChkcml2ZXItPm1heF9zcGVlZCA9PSBVU0JfU1BFRURf VU5LTk9XTikKKwlzd2l0Y2ggKGctPnNwZWVkKSB7CisJLyogQWxsIHRoZSBzcGVlZHMgd2Ugc3Vw cG9ydCAqLworCWNhc2UgVVNCX1NQRUVEX0xPVzoKKwljYXNlIFVTQl9TUEVFRF9GVUxMOgorCWNh c2UgVVNCX1NQRUVEX0hJR0g6CisJY2FzZSBVU0JfU1BFRURfU1VQRVI6CisJCWJyZWFrOworCWRl ZmF1bHQ6CisJCWRldl9lcnIoZHVtbXlfZGV2KGR1bV9oY2QpLCAiVW5zdXBwb3J0ZWQgZHJpdmVy IG1heCBzcGVlZCAlZFxuIiwKKwkJCQlkcml2ZXItPm1heF9zcGVlZCk7CiAJCXJldHVybiAtRUlO VkFMOworCX0KIAogCS8qCiAJICogU0xBVkUgc2lkZSBpbml0IC4uLiB0aGUgbGF5ZXIgYWJvdmUg aGFyZHdhcmUsIHdoaWNoCkBAIC0xNzg0LDkgKzE3OTQsMTAgQEAgc3RhdGljIHZvaWQgZHVtbXlf dGltZXIoc3RydWN0IHRpbWVyX2xpcwogCQkvKiBCdXMgc3BlZWQgaXMgNTAwMDAwIGJ5dGVzL21z LCBzbyB1c2UgYSBsaXR0bGUgbGVzcyAqLwogCQl0b3RhbCA9IDQ5MDAwMDsKIAkJYnJlYWs7Ci0J ZGVmYXVsdDoKKwlkZWZhdWx0OgkvKiBDYW4ndCBoYXBwZW4gKi8KIAkJZGV2X2VycihkdW1teV9k ZXYoZHVtX2hjZCksICJib2d1cyBkZXZpY2Ugc3BlZWRcbiIpOwotCQlyZXR1cm47CisJCXRvdGFs ID0gMDsKKwkJYnJlYWs7CiAJfQogCiAJLyogRklYTUUgaWYgSFogIT0gMTAwMCB0aGlzIHdpbGwg cHJvYmFibHkgbWlzYmVoYXZlIC4uLiAqLwpAQCAtMTgyOCw3ICsxODM5LDcgQEAgcmVzdGFydDoK IAogCQkvKiBVc2VkIHVwIHRoaXMgZnJhbWUncyBiYW5kd2lkdGg/ICovCiAJCWlmICh0b3RhbCA8 PSAwKQotCQkJYnJlYWs7CisJCQljb250aW51ZTsKIAogCQkvKiBmaW5kIHRoZSBnYWRnZXQncyBl cCBmb3IgdGhpcyByZXF1ZXN0IChpZiBjb25maWd1cmVkKSAqLwogCQlhZGRyZXNzID0gdXNiX3Bp cGVlbmRwb2ludCAodXJiLT5waXBlKTsK From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.9 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A644DC10F0E for ; Thu, 18 Apr 2019 17:12:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7B6672171F for ; Thu, 18 Apr 2019 17:12:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389593AbfDRRMJ (ORCPT ); Thu, 18 Apr 2019 13:12:09 -0400 Received: from iolanthe.rowland.org ([192.131.102.54]:48580 "HELO iolanthe.rowland.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1733192AbfDRRMI (ORCPT ); Thu, 18 Apr 2019 13:12:08 -0400 Received: (qmail 2385 invoked by uid 2102); 18 Apr 2019 13:12:07 -0400 Received: from localhost (sendmail-bs@127.0.0.1) by localhost with SMTP; 18 Apr 2019 13:12:07 -0400 Date: Thu, 18 Apr 2019 13:12:07 -0400 (EDT) From: Alan Stern X-X-Sender: stern@iolanthe.rowland.org To: Greg KH cc: andreyknvl@google.com, , USB list , Subject: [PATCH] USB: dummy-hcd: Fix failure to give back unlinked URBs In-Reply-To: <00000000000054e5e70586bf46cc@google.com> Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Message-ID: <20190418171207.P7livWZZ1WKKjCln99lxT0JM8z_xuJUJgOeWyopowDg@z> The syzkaller USB fuzzer identified a failure mode in which dummy-hcd would never give back an unlinked URB. This causes usb_kill_urb() to hang, leading to WARNINGs and unkillable threads. In dummy-hcd, all URBs are given back by the dummy_timer() routine as it scans through the list of pending URBS. Failure to give back URBs can be caused by failure to start or early exit from the scanning loop. The code currently has two such pathways: One is triggered when an unsupported bus transfer speed is encountered, and the other by exhausting the simulated bandwidth for USB transfers during a frame. This patch removes those two paths, thereby allowing all unlinked URBs to be given back in a timely manner. It adds a check for the bus speed when the gadget first starts running, so that dummy_timer() will never thereafter encounter an unsupported speed. And it prevents the loop from exiting as soon as the total bandwidth has been used up (the scanning loop continues, giving back unlinked URBs as they are found, but not transferring any more data). Thanks to Andrey Konovalov for manually running the syzkaller fuzzer to help track down the source of the bug. Signed-off-by: Alan Stern Reported-and-tested-by: syzbot+d919b0f29d7b5a4994b9@syzkaller.appspotmail.com CC: --- [as1889] drivers/usb/gadget/udc/dummy_hcd.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) Index: usb-devel/drivers/usb/gadget/udc/dummy_hcd.c =================================================================== --- usb-devel.orig/drivers/usb/gadget/udc/dummy_hcd.c +++ usb-devel/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,9 +1794,10 @@ 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; + total = 0; + break; } /* FIXME if HZ != 1000 this will probably misbehave ... */ @@ -1828,7 +1839,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);