Merge tag 'usb-5.9-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 3 Oct 2020 18:47:35 +0000 (11:47 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 3 Oct 2020 18:47:35 +0000 (11:47 -0700)
Pull USB/PHY fixes from Greg KH:
 "Here are some small USB and PHY driver fixes for 5.9-rc8

  The PHY driver fix resolves an issue found by Dan Carpenter for a
  memory leak.

  The USB fixes fall into two groups:

   - usb gadget fix from Bryan that is a fix for a previous security fix
     that showed up in in-the-wild testing

   - usb core driver matching bugfixes. This fixes a bug that has
     plagued the both the usbip driver and syzbot testing tools this -rc
     release cycle. All is now working properly so usbip connections
     will work, and syzbot can get back to fuzzing USB drivers properly.

  All have been in linux-next for a while with no reported issues"

* tag 'usb-5.9-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usbcore/driver: Accommodate usbip
  usbcore/driver: Fix incorrect downcast
  usbcore/driver: Fix specific driver selection
  Revert "usbip: Implement a match function to fix usbip"
  USB: gadget: f_ncm: Fix NDP16 datagram validation
  phy: ti: am654: Fix a leak in serdes_am654_probe()

drivers/phy/ti/phy-am654-serdes.c
drivers/usb/core/driver.c
drivers/usb/gadget/function/f_ncm.c
drivers/usb/usbip/stub_dev.c

index a174b3c..819c49a 100644 (file)
@@ -725,8 +725,10 @@ static int serdes_am654_probe(struct platform_device *pdev)
        pm_runtime_enable(dev);
 
        phy = devm_phy_create(dev, NULL, &ops);
-       if (IS_ERR(phy))
-               return PTR_ERR(phy);
+       if (IS_ERR(phy)) {
+               ret = PTR_ERR(phy);
+               goto clk_err;
+       }
 
        phy_set_drvdata(phy, am654_phy);
        phy_provider = devm_of_phy_provider_register(dev, serdes_am654_xlate);
index 7e73e98..b351962 100644 (file)
@@ -269,8 +269,30 @@ static int usb_probe_device(struct device *dev)
        if (error)
                return error;
 
+       /* Probe the USB device with the driver in hand, but only
+        * defer to a generic driver in case the current USB
+        * device driver has an id_table or a match function; i.e.,
+        * when the device driver was explicitly matched against
+        * a device.
+        *
+        * If the device driver does not have either of these,
+        * then we assume that it can bind to any device and is
+        * not truly a more specialized/non-generic driver, so a
+        * return value of -ENODEV should not force the device
+        * to be handled by the generic USB driver, as there
+        * can still be another, more specialized, device driver.
+        *
+        * This accommodates the usbip driver.
+        *
+        * TODO: What if, in the future, there are multiple
+        * specialized USB device drivers for a particular device?
+        * In such cases, there is a need to try all matching
+        * specialised device drivers prior to setting the
+        * use_generic_driver bit.
+        */
        error = udriver->probe(udev);
-       if (error == -ENODEV && udriver != &usb_generic_driver) {
+       if (error == -ENODEV && udriver != &usb_generic_driver &&
+           (udriver->id_table || udriver->match)) {
                udev->use_generic_driver = 1;
                return -EPROBE_DEFER;
        }
@@ -831,14 +853,17 @@ static int usb_device_match(struct device *dev, struct device_driver *drv)
                udev = to_usb_device(dev);
                udrv = to_usb_device_driver(drv);
 
-               if (udrv->id_table &&
-                   usb_device_match_id(udev, udrv->id_table) != NULL) {
-                       return 1;
-               }
+               if (udrv->id_table)
+                       return usb_device_match_id(udev, udrv->id_table) != NULL;
 
                if (udrv->match)
                        return udrv->match(udev);
-               return 0;
+
+               /* If the device driver under consideration does not have a
+                * id_table or a match function, then let the driver's probe
+                * function decide.
+                */
+               return 1;
 
        } else if (is_usb_interface(dev)) {
                struct usb_interface *intf;
@@ -905,26 +930,19 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
        return 0;
 }
 
-static bool is_dev_usb_generic_driver(struct device *dev)
-{
-       struct usb_device_driver *udd = dev->driver ?
-               to_usb_device_driver(dev->driver) : NULL;
-
-       return udd == &usb_generic_driver;
-}
-
 static int __usb_bus_reprobe_drivers(struct device *dev, void *data)
 {
        struct usb_device_driver *new_udriver = data;
        struct usb_device *udev;
        int ret;
 
-       if (!is_dev_usb_generic_driver(dev))
+       /* Don't reprobe if current driver isn't usb_generic_driver */
+       if (dev->driver != &usb_generic_driver.drvwrap.driver)
                return 0;
 
        udev = to_usb_device(dev);
        if (usb_device_match_id(udev, new_udriver->id_table) == NULL &&
-           (!new_udriver->match || new_udriver->match(udev) != 0))
+           (!new_udriver->match || new_udriver->match(udev) == 0))
                return 0;
 
        ret = device_reprobe(dev);
index b4206b0..1f63875 100644 (file)
@@ -1189,7 +1189,6 @@ static int ncm_unwrap_ntb(struct gether *port,
        const struct ndp_parser_opts *opts = ncm->parser_opts;
        unsigned        crc_len = ncm->is_crc ? sizeof(uint32_t) : 0;
        int             dgram_counter;
-       bool            ndp_after_header;
 
        /* dwSignature */
        if (get_unaligned_le32(tmp) != opts->nth_sign) {
@@ -1216,7 +1215,6 @@ static int ncm_unwrap_ntb(struct gether *port,
        }
 
        ndp_index = get_ncm(&tmp, opts->ndp_index);
-       ndp_after_header = false;
 
        /* Run through all the NDP's in the NTB */
        do {
@@ -1232,8 +1230,6 @@ static int ncm_unwrap_ntb(struct gether *port,
                             ndp_index);
                        goto err;
                }
-               if (ndp_index == opts->nth_size)
-                       ndp_after_header = true;
 
                /*
                 * walk through NDP
@@ -1312,37 +1308,13 @@ static int ncm_unwrap_ntb(struct gether *port,
                        index2 = get_ncm(&tmp, opts->dgram_item_len);
                        dg_len2 = get_ncm(&tmp, opts->dgram_item_len);
 
-                       if (index2 == 0 || dg_len2 == 0)
-                               break;
-
                        /* wDatagramIndex[1] */
-                       if (ndp_after_header) {
-                               if (index2 < opts->nth_size + opts->ndp_size) {
-                                       INFO(port->func.config->cdev,
-                                            "Bad index: %#X\n", index2);
-                                       goto err;
-                               }
-                       } else {
-                               if (index2 < opts->nth_size + opts->dpe_size) {
-                                       INFO(port->func.config->cdev,
-                                            "Bad index: %#X\n", index2);
-                                       goto err;
-                               }
-                       }
                        if (index2 > block_len - opts->dpe_size) {
                                INFO(port->func.config->cdev,
                                     "Bad index: %#X\n", index2);
                                goto err;
                        }
 
-                       /* wDatagramLength[1] */
-                       if ((dg_len2 < 14 + crc_len) ||
-                                       (dg_len2 > frame_max)) {
-                               INFO(port->func.config->cdev,
-                                    "Bad dgram length: %#X\n", dg_len);
-                               goto err;
-                       }
-
                        /*
                         * Copy the data into a new skb.
                         * This ensures the truesize is correct
@@ -1359,6 +1331,8 @@ static int ncm_unwrap_ntb(struct gether *port,
                        ndp_len -= 2 * (opts->dgram_item_len * 2);
 
                        dgram_counter++;
+                       if (index2 == 0 || dg_len2 == 0)
+                               break;
                } while (ndp_len > 2 * (opts->dgram_item_len * 2));
        } while (ndp_index);
 
index 9d7d642..2305d42 100644 (file)
@@ -461,11 +461,6 @@ static void stub_disconnect(struct usb_device *udev)
        return;
 }
 
-static bool usbip_match(struct usb_device *udev)
-{
-       return true;
-}
-
 #ifdef CONFIG_PM
 
 /* These functions need usb_port_suspend and usb_port_resume,
@@ -491,7 +486,6 @@ struct usb_device_driver stub_driver = {
        .name           = "usbip-host",
        .probe          = stub_probe,
        .disconnect     = stub_disconnect,
-       .match          = usbip_match,
 #ifdef CONFIG_PM
        .suspend        = stub_suspend,
        .resume         = stub_resume,