Skip to content

Commit 21851aa

Browse files
AlanSterngregkh
authored andcommitted
USB: core: Fix misleading driver bug report
[ Upstream commit ac85413 ] The syzbot fuzzer found a race between URB submission to endpoint 0 and device reset. Namely, during the reset we call usb_ep0_reinit() because the characteristics of ep0 may have changed (if the reset follows a firmware update, for example). While usb_ep0_reinit() is running there is a brief period during which the pointers stored in udev->ep_in[0] and udev->ep_out[0] are set to NULL, and if an URB is submitted to ep0 during that period, usb_urb_ep_type_check() will report it as a driver bug. In the absence of those pointers, the routine thinks that the endpoint doesn't exist. The log message looks like this: ------------[ cut here ]------------ usb 2-1: BOGUS urb xfer, pipe 2 != type 2 WARNING: CPU: 0 PID: 9241 at drivers/usb/core/urb.c:478 usb_submit_urb+0x1188/0x1460 drivers/usb/core/urb.c:478 Now, although submitting an URB while the device is being reset is a questionable thing to do, it shouldn't count as a driver bug as severe as submitting an URB for an endpoint that doesn't exist. Indeed, endpoint 0 always exists, even while the device is in its unconfigured state. To prevent these misleading driver bug reports, this patch updates usb_disable_endpoint() to avoid clearing the ep_in[] and ep_out[] pointers when the endpoint being disabled is ep0. There's no danger of leaving a stale pointer in place, because the usb_host_endpoint structure being pointed to is stored permanently in udev->ep0; it doesn't get deallocated until the entire usb_device structure does. Reported-and-tested-by: [email protected] Signed-off-by: Alan Stern <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 1de356b commit 21851aa

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

drivers/usb/core/message.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,11 +1081,11 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
10811081

10821082
if (usb_endpoint_out(epaddr)) {
10831083
ep = dev->ep_out[epnum];
1084-
if (reset_hardware)
1084+
if (reset_hardware && epnum != 0)
10851085
dev->ep_out[epnum] = NULL;
10861086
} else {
10871087
ep = dev->ep_in[epnum];
1088-
if (reset_hardware)
1088+
if (reset_hardware && epnum != 0)
10891089
dev->ep_in[epnum] = NULL;
10901090
}
10911091
if (ep) {

0 commit comments

Comments
 (0)