Skip to content

Commit

Permalink
Merge tag 'usb-5.9-rc8' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/gregkh/usb

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()
  • Loading branch information
Linus Torvalds committed Oct 3, 2020
2 parents f35c08e + 25b9e4b commit 5f05663
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 52 deletions.
6 changes: 4 additions & 2 deletions drivers/phy/ti/phy-am654-serdes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
50 changes: 34 additions & 16 deletions drivers/usb/core/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
30 changes: 2 additions & 28 deletions drivers/usb/gadget/function/f_ncm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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);

Expand Down
6 changes: 0 additions & 6 deletions drivers/usb/usbip/stub_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down

0 comments on commit 5f05663

Please sign in to comment.