Skip to content

Commit 4df30e7

Browse files
m-v-bgregkh
authored andcommitted
usbcore/driver: Fix incorrect downcast
This commit resolves a minor bug in the selection/discovery of more specific USB device drivers for devices that are currently bound to generic USB device drivers. The bug is related to the way a candidate USB device driver is compared against the generic USB device driver. The code in is_dev_usb_generic_driver() assumes that the device driver in question is a USB device driver by calling to_usb_device_driver(dev->driver) to downcast; however I have observed that this assumption is not always true, through code instrumentation. This commit avoids the incorrect downcast altogether by comparing the USB device's driver (i.e., dev->driver) to the generic USB device driver directly. This method was suggested by Alan Stern. This bug was found while investigating Andrey Konovalov's report indicating usbip device driver misbehaviour with the recently merged generic USB device driver selection feature. The report is linked below. Fixes: d5643d2 ("USB: Fix device driver race") Cc: <[email protected]> # 5.8 Cc: Greg Kroah-Hartman <[email protected]> Cc: Alan Stern <[email protected]> Cc: Bastien Nocera <[email protected]> Cc: Shuah Khan <[email protected]> Cc: Valentina Manea <[email protected]> Cc: <[email protected]> Tested-by: Andrey Konovalov <[email protected]> Signed-off-by: M. Vefa Bicakci <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent aea850c commit 4df30e7

File tree

1 file changed

+2
-9
lines changed

1 file changed

+2
-9
lines changed

drivers/usb/core/driver.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -905,21 +905,14 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
905905
return 0;
906906
}
907907

908-
static bool is_dev_usb_generic_driver(struct device *dev)
909-
{
910-
struct usb_device_driver *udd = dev->driver ?
911-
to_usb_device_driver(dev->driver) : NULL;
912-
913-
return udd == &usb_generic_driver;
914-
}
915-
916908
static int __usb_bus_reprobe_drivers(struct device *dev, void *data)
917909
{
918910
struct usb_device_driver *new_udriver = data;
919911
struct usb_device *udev;
920912
int ret;
921913

922-
if (!is_dev_usb_generic_driver(dev))
914+
/* Don't reprobe if current driver isn't usb_generic_driver */
915+
if (dev->driver != &usb_generic_driver.drvwrap.driver)
923916
return 0;
924917

925918
udev = to_usb_device(dev);

0 commit comments

Comments
 (0)