linux/Documentation/usb
Alan Stern fb2d3ede3c USB: core: Fix bug caused by duplicate interface PM usage counter
commit c2b71462d2 upstream.

The syzkaller fuzzer reported a bug in the USB hub driver which turned
out to be caused by a negative runtime-PM usage counter.  This allowed
a hub to be runtime suspended at a time when the driver did not expect
it.  The symptom is a WARNING issued because the hub's status URB is
submitted while it is already active:

	URB 0000000031fb463e submitted while active
	WARNING: CPU: 0 PID: 2917 at drivers/usb/core/urb.c:363

The negative runtime-PM usage count was caused by an unfortunate
design decision made when runtime PM was first implemented for USB.
At that time, USB class drivers were allowed to unbind from their
interfaces without balancing the usage counter (i.e., leaving it with
a positive count).  The core code would take care of setting the
counter back to 0 before allowing another driver to bind to the
interface.

Later on when runtime PM was implemented for the entire kernel, the
opposite decision was made: Drivers were required to balance their
runtime-PM get and put calls.  In order to maintain backward
compatibility, however, the USB subsystem adapted to the new
implementation by keeping an independent usage counter for each
interface and using it to automatically adjust the normal usage
counter back to 0 whenever a driver was unbound.

This approach involves duplicating information, but what is worse, it
doesn't work properly in cases where a USB class driver delays
decrementing the usage counter until after the driver's disconnect()
routine has returned and the counter has been adjusted back to 0.
Doing so would cause the usage counter to become negative.  There's
even a warning about this in the USB power management documentation!

As it happens, this is exactly what the hub driver does.  The
kick_hub_wq() routine increments the runtime-PM usage counter, and the
corresponding decrement is carried out by hub_event() in the context
of the hub_wq work-queue thread.  This work routine may sometimes run
after the driver has been unbound from its interface, and when it does
it causes the usage counter to go negative.

It is not possible for hub_disconnect() to wait for a pending
hub_event() call to finish, because hub_disconnect() is called with
the device lock held and hub_event() acquires that lock.  The only
feasible fix is to reverse the original design decision: remove the
duplicate interface-specific usage counter and require USB drivers to
balance their runtime PM gets and puts.  As far as I know, all
existing drivers currently do this.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-and-tested-by: syzbot+7634edaea4d0b341c625@syzkaller.appspotmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.16:
 - Adjust documentation filename
 - Don't add ReST markup in documentation
 - Update use of pm_usage_cnt in poseidon driver, which has been
   removed upstream]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
History 2019-08-13 12:39:12 +01:00
..
acm.txt USB: small update to Documentation/usb/acm.txt 2007-01-05 12:19:09 -08:00
anchors.txt trivial: Miscellaneous documentation typo fixes 2009-06-12 18:01:47 +02:00
authorization.txt USB: Fix sysfs paths in documentation 2009-09-23 06:46:41 -07:00
bulk-streams.txt USB: Support for allocating USB 3.0 streams. 2010-05-20 13:21:38 -07:00
callbacks.txt USB: documentation update for the pre_reset method 2011-04-29 17:24:29 -07:00
chipidea.txt Doc: usb: chipidea: need to build both kernel Image and modules 2014-05-23 11:36:44 +09:00
CREDITS documentation: convert the Documentation directory to UTF-8 2007-05-09 08:58:19 +02:00
dma.txt doc: fix broken references 2011-09-27 18:08:04 +02:00
dwc3.txt doc: fix a few typos 2012-04-05 17:02:52 -07:00
ehci.txt USB: EHCI: Allow users to override 80% max periodic bandwidth 2011-07-08 14:51:33 -07:00
error-codes.txt USB: report submission of active URBs 2012-11-11 18:10:46 -08:00
functionfs.txt FunctionFS: enable multiple functions 2012-05-14 09:25:44 -07:00
gadget_configfs.txt doc: usb: Fix typo in Documentation/usb/gadget_configs.txt 2013-10-31 13:31:39 +01:00
gadget_hid.txt USB: Documentation: Use correct character in gadget_hid.txt 2011-07-01 14:43:27 -07:00
gadget_multi.txt doc: Fix typo in USB Gadget Documentation 2014-01-10 15:33:54 +01:00
gadget_printer.txt USB: add Printer Gadget Driver 2008-02-01 14:34:49 -08:00
gadget_serial.txt USB: gadget: g_serial: INF file updated 2010-08-10 14:35:37 -07:00
hotplug.txt Finally eradicate CONFIG_HOTPLUG 2013-06-03 14:20:18 -07:00
iuu_phoenix.txt USB: add iuu_phoenix driver 2008-02-01 14:34:47 -08:00
linux-cdc-acm.inf USB: linux-cdc-acm.inf: add support for the acm_ms gadget 2011-11-29 09:59:29 +09:00
linux.inf USB: gadget: g_multi: fixed vendor and product ID in inf files 2011-04-29 16:45:22 -07:00
mass-storage.txt doc: spelling error changes 2014-05-05 15:32:05 +02:00
misc_usbsevseg.txt USB: Added driver for a Delcom USB 7-segment LED Display 2008-10-17 14:40:51 -07:00
mtouchusb.txt Documentation: Fix Broken URL "freshmeat" 2012-02-21 11:43:45 +01:00
ohci.txt Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
persist.txt usb: add decriptor of persist fail for some morph usb devices 2012-08-10 12:06:39 -07:00
power-management.txt USB: core: Fix bug caused by duplicate interface PM usage counter 2019-08-13 12:39:12 +01:00
proc_usb_info.txt proc_usb_info.txt: Correct documentation about endianness of config descriptors 2013-08-12 12:24:27 -07:00
rio.txt Fix typos in /Documentation : 'T'' 2006-11-30 04:55:36 +01:00
URB.txt USB: URB documentation: claim complete() will be run with IRQs enabled 2013-08-12 11:43:48 -07:00
usb-help.txt USB:Update mailing list information in documentation 2008-03-10 16:42:27 -07:00
usb-serial.txt USB: serial: keyspan_pda: fix Entrega company name spelling 2015-04-13 16:48:55 +01:00
usbmon.txt usb/usbmon: correct the data interpretation of usbmon's output 2012-04-06 13:54:00 -07:00
wusb-cbaf doc: fix a few typos 2012-04-05 17:02:52 -07:00
WUSB-Design-overview.txt doc: fix double words 2014-03-21 13:16:58 +01:00