linux/Documentation/driver-api
Alan Stern c2b71462d2 USB: core: Fix bug caused by duplicate interface PM usage counter
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
CC: <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-04-19 21:15:13 +02:00
..
80211 mac80211: fix missing/malformed documentation 2019-02-01 12:11:13 +01:00
dmaengine doc:dmaengine: clarify DMA desc. pointer after submission 2019-02-11 08:40:16 -07:00
firmware Documentation: driver-api: add stratix10 service layer 2018-11-26 20:15:07 +01:00
fpga docs: fpga: document programming fpgas using regions 2018-10-16 11:13:50 +02:00
gpio Documentation: gpio: legacy: Don't use POLLERR for poll(2) 2019-02-20 10:53:52 +01:00
i3c docs: driver-api: Add I3C documentation 2018-11-12 10:33:49 +01:00
iio docs: driver-api: iio: fix errors in documentation 2019-03-04 12:51:17 -07:00
pci PCI/P2PDMA: Clean up documentation and kernel-doc 2018-12-11 07:53:07 -06:00
pm Documentation: driver-api: PM: Add cpuidle document 2019-01-17 22:15:20 +01:00
soundwire Documentation: soundwire: fix stream.rst markup warnings 2018-09-17 09:12:36 -07:00
usb USB: core: Fix bug caused by duplicate interface PM usage counter 2019-04-19 21:15:13 +02:00
basics.rst docs: Introduce deprecated APIs list 2018-10-18 12:22:43 -06:00
clk.rst This time we have a good set of changes to the core framework that do some 2018-06-09 12:06:24 -07:00
component.rst component: Add documentation 2019-02-08 16:57:38 +01:00
conf.py doc-rst: make driver-api folder buildable stand-alone 2016-10-26 17:25:00 -06:00
device-io.rst docs: Convert the deviceio template to RST 2017-01-31 17:31:21 -07:00
device_connection.rst Documentation: driver-api: fix device_connection.rst kernel-doc error 2018-04-27 17:17:34 -06:00
device_link.rst typed componented support + i915/snd-hda changes 2019-02-11 20:32:31 +01:00
dma-buf.rst dma-fence: Polish kernel-doc for dma-fence.c 2018-07-04 12:18:37 +02:00
edac.rst edac.rst: move concepts dictionary from edac.h 2016-12-15 08:58:12 -02:00
firewire.rst FireWire: add driver-api Introduction section 2018-09-06 09:41:16 -06:00
frame-buffer.rst
hsi.rst docs: split up serial-interfaces.rst 2016-09-06 09:14:52 -06:00
i2c.rst Merge branch 'i2c/for-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux 2017-07-12 10:04:56 -07:00
index.rst component: Add documentation 2019-02-08 16:57:38 +01:00
infrastructure.rst dma-mapping: move all DMA mapping code to kernel/dma 2018-06-14 08:50:37 +02:00
input.rst
libata.rst libata: remove ata_sff_data_xfer_noirq() 2018-07-11 10:45:28 -07:00
message-based.rst docs: Don't format internal MPT docs 2016-09-06 09:15:48 -06:00
misc_devices.rst docs-rst: core_api: move driver-specific stuff to drivers_api 2017-04-02 14:17:43 -06:00
miscellaneous.rst docs: driver-api: Remove trailing blank line 2017-08-07 14:27:45 -06:00
mtdnand.rst mtd: rawnand: Deprecate ->chip_delay 2018-10-03 11:12:25 +02:00
pinctl.rst pinctrl.txt: Remove outdated information 2019-01-28 10:07:58 +01:00
rapidio.rst docs-rst: convert rapidio book to ReST 2017-05-16 08:44:16 -03:00
regulator.rst docs: Convert the regulator docbook to RST 2017-01-31 17:31:41 -07:00
s390-drivers.rst s390/docs: reword airq section 2018-02-02 10:47:15 +01:00
scsi.rst scsi: target: add driver-api document 2018-04-20 19:14:40 -04:00
slimbus.rst slimbus: stream: add stream support 2018-07-07 17:25:23 +02:00
sound.rst
spi.rst docs: split up serial-interfaces.rst 2016-09-06 09:14:52 -06:00
target.rst scsi: target: add driver-api document 2018-04-20 19:14:40 -04:00
uio-howto.rst docs/uio: fix a grammar nitpick 2018-10-16 11:15:51 +02:00
vme.rst docs: Update VME documentation to include kerneldoc comments 2017-03-17 15:10:49 +09:00
w1.rst There has been a fair amount of activity in the docs tree this time 2017-07-03 21:13:25 -07:00