USB: Fix unplug of device with active streams
authorMatthew Wilcox <willy@linux.intel.com>
Tue, 28 Sep 2010 04:57:32 +0000 (00:57 -0400)
committerBrad Figg <brad.figg@canonical.com>
Wed, 27 Apr 2011 18:42:32 +0000 (11:42 -0700)
commitd7b03472ec2353575de9f5b537e10d4b4197164a
tree6b4e04bb80251a67b58750c85d77e1c5ed83cf36
parentfc4c57e02daa2699f54cf2ae92986484264880a3
USB: Fix unplug of device with active streams

BugLink: http://bugs.launchpad.net/bugs/769042

commit b214f191d95ba4b5a35aebd69cd129cf7e3b1884 upstream.

If I unplug a device while the UAS driver is loaded, I get an oops
in usb_free_streams().  This is because usb_unbind_interface() calls
usb_disable_interface() which calls usb_disable_endpoint() which sets
ep_out and ep_in to NULL.  Then the UAS driver calls usb_pipe_endpoint()
which returns a NULL pointer and passes an array of NULL pointers to
usb_free_streams().

I think the correct fix for this is to check for the NULL pointer
in usb_free_streams() rather than making the driver check for this
situation.  My original patch for this checked for dev->state ==
USB_STATE_NOTATTACHED, but the call to usb_disable_interface() is
conditional, so not all drivers would want this check.

Note from Sarah Sharp: This patch does avoid a potential dereference,
but the real fix (which will be implemented later) is to set the
.soft_unbind flag in the usb_driver structure for the UAS driver, and
all drivers that allocate streams.  The driver should free any streams
when it is unbound from the interface.  This avoids leaking stream rings
in the xHCI driver when usb_disable_interface() is called.

This should be queued for stable trees back to 2.6.35.

Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com>
drivers/usb/core/hcd.c