[PATCH v4] Move DWC2 driver out of staging

Alan Stern stern at rowland.harvard.edu
Sat Feb 1 17:04:56 UTC 2014


On Fri, 31 Jan 2014, Stephen Warren wrote:

> This is due to the following code:
> 
> static void _dwc2_hcd_endpoint_reset(struct usb_hcd *hcd,
> 				     struct usb_host_endpoint *ep)
> {
> 	struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
> ...
> 	struct usb_device *udev;
> ...
> 	udev = to_usb_device(hsotg->dev);
> ...
> 	usb_settoggle(udev, epnum, is_out, 0);
> 	if (is_control)
> 		usb_settoggle(udev, epnum, !is_out, 0);
> 
> The problem is that hsotg->dev is assigned as follows:
> 
> static int dwc2_driver_probe(struct platform_device *dev)
> ...
> 	hsotg = devm_kzalloc(&dev->dev, sizeof(*hsotg), GFP_KERNEL);
> ...
> 	hsotg->dev = &dev->dev;
> 
> As such, it's not legal to call to_usb_device() on it.

This clearly is a bug.  I suspect the driver has other bugs too, such
as not holding the private lock over a large enough region.

> What ends up happening, simply due to memory allocation order, is that
> the memory writes inside usb_settoggle() end up setting the SDHCI struct
> platform_device's num_resources to 0, so that it's call to
> platform_get_resource() fails.
> 
> With the DWC2 move patch reverted, some other random piece of memory is
> being corrupted, which just happens not to cause any visible problem.
> Likely it's some other struct platform_device that's already had its
> resources read by the time DWC2 probes and corrupts them.
> 
> (Yes, this was hard to find!)
> 
> I honestly can't see how to solve this myself, since the whole DWC2
> driver doesn't seem to have a struct usb_device * hanging around that we
> can stash somewhere for it to look up later. Perhaps someone more
> familiar with the USB stack can help with that.

The correct solution is to set

	qh = ep->hcpriv;
	udev = qh->udev;

However, the driver doesn't store udev in qh (dwc2_qh_init() should do
this, but it doesn't).  In fact, the field doesn't even exist.

Alan Stern



More information about the devel mailing list