mirror-linux/drivers/usb/gadget/udc
Alan Stern 8d63c83d8e USB: gadget: dummy-hcd: Fix locking bug in RT-enabled kernels
Yunseong Kim and the syzbot fuzzer both reported a problem in
RT-enabled kernels caused by the way dummy-hcd mixes interrupt
management and spin-locking.  The pattern was:

	local_irq_save(flags);
	spin_lock(&dum->lock);
	...
	spin_unlock(&dum->lock);
	...		// calls usb_gadget_giveback_request()
	local_irq_restore(flags);

The code was written this way because usb_gadget_giveback_request()
needs to be called with interrupts disabled and the private lock not
held.

While this pattern works fine in non-RT kernels, it's not good when RT
is enabled.  RT kernels handle spinlocks much like mutexes; in particular,
spin_lock() may sleep.  But sleeping is not allowed while local
interrupts are disabled.

To fix the problem, rewrite the code to conform to the pattern used
elsewhere in dummy-hcd and other UDC drivers:

	spin_lock_irqsave(&dum->lock, flags);
	...
	spin_unlock(&dum->lock);
	usb_gadget_giveback_request(...);
	spin_lock(&dum->lock);
	...
	spin_unlock_irqrestore(&dum->lock, flags);

This approach satisfies the RT requirements.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Cc: stable <stable@kernel.org>
Fixes: b4dbda1a22 ("USB: dummy-hcd: disable interrupts during req->complete")
Reported-by: Yunseong Kim <ysk@kzalloc.com>
Closes: <https://lore.kernel.org/linux-usb/5b337389-73b9-4ee4-a83e-7e82bf5af87a@kzalloc.com/>
Reported-by: syzbot+8baacc4139f12fa77909@syzkaller.appspotmail.com
Closes: <https://lore.kernel.org/linux-usb/68ac2411.050a0220.37038e.0087.GAE@google.com/>
Tested-by: syzbot+8baacc4139f12fa77909@syzkaller.appspotmail.com
CC: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
CC: stable@vger.kernel.org
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://lore.kernel.org/r/bb192ae2-4eee-48ee-981f-3efdbbd0d8f0@rowland.harvard.edu
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-09-06 15:29:50 +02:00
..
aspeed-vhub usb: gadget: aspeed: Add NULL pointer check in ast_vhub_init_dev() 2025-03-14 09:17:26 +01:00
bdc Merge 6.12-rc3 into usb-next 2024-10-14 08:03:44 +02:00
cdns2 USB: gadget: Use str_enable_disable-like helpers 2025-01-15 18:28:13 +01:00
Kconfig usb: Remove orphaned UDC drivers 2025-04-11 16:11:25 +02:00
Makefile usb: Remove orphaned UDC drivers 2025-04-11 16:11:25 +02:00
amd5536udc.h
amd5536udc_pci.c usb: gadget: udc: fix NULL dereference in remove() 2023-05-29 15:24:24 +01:00
aspeed_udc.c usb: Switch back to struct platform_driver::remove() 2024-10-04 15:13:03 +02:00
at91_udc.c treewide, timers: Rename from_timer() to timer_container_of() 2025-06-08 09:07:37 +02:00
at91_udc.h
atmel_usba_udc.c usb: Switch back to struct platform_driver::remove() 2024-10-04 15:13:03 +02:00
atmel_usba_udc.h
bcm63xx_udc.c usb: Switch back to struct platform_driver::remove() 2024-10-04 15:13:03 +02:00
core.c USB: gadget: udc: fix const issue in gadget_match_driver() 2025-05-23 12:34:09 +02:00
dummy_hcd.c USB: gadget: dummy-hcd: Fix locking bug in RT-enabled kernels 2025-09-06 15:29:50 +02:00
fsl_qe_udc.c usb: Switch back to struct platform_driver::remove() 2024-10-04 15:13:03 +02:00
fsl_qe_udc.h
fsl_udc_core.c USB: gadget: Use str_enable_disable-like helpers 2025-01-15 18:28:13 +01:00
fsl_usb2_udc.h usb: gadget: fsl-udc: Replace custom log wrappers by dev_{err,warn,dbg,vdbg} 2024-03-05 13:29:03 +00:00
goku_udc.c move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
goku_udc.h
gr_udc.c usb: Switch back to struct platform_driver::remove() 2024-10-04 15:13:03 +02:00
gr_udc.h
lpc32xx_udc.c usb: gadget: lpc32xx_udc: Use USB API functions rather than constants 2025-05-21 13:13:24 +02:00
m66592-udc.c usb: gadget: m66592-udc: Use USB API functions rather than constants 2025-06-19 12:23:59 +02:00
m66592-udc.h
max3420_udc.c usb: gadget: max3420_udc: Follow renaming of SPI "master" to "controller" 2024-02-08 11:54:57 +00:00
net2280.c usb: gadget: net2280: Use USB API functions rather than constants 2025-06-19 12:24:06 +02:00
net2280.h
omap_udc.c treewide, timers: Rename from_timer() to timer_container_of() 2025-06-08 09:07:37 +02:00
omap_udc.h
pch_udc.c usb: gadget: pch_udc: Use USB API functions rather than constants 2025-06-19 12:24:05 +02:00
pxa25x_udc.c usb: gadget: pxa25x_udc: Switch to use devm_gpio_request_one() 2025-06-10 09:59:54 +02:00
pxa25x_udc.h
pxa27x_udc.c USB: gadget: Use str_enable_disable-like helpers 2025-01-15 18:28:13 +01:00
pxa27x_udc.h
r8a66597-udc.c treewide, timers: Rename from_timer() to timer_container_of() 2025-06-08 09:07:37 +02:00
r8a66597-udc.h
renesas_usb3.c usb: gadget: udc: renesas_usb3: fix device leak at unbind 2025-07-25 10:50:43 +02:00
renesas_usbf.c usb: Switch back to struct platform_driver::remove() 2024-10-04 15:13:03 +02:00
rzv2m_usb3drd.c usb: Switch back to struct platform_driver::remove() 2024-10-04 15:13:03 +02:00
snps_udc_core.c treewide: Switch/rename to timer_delete[_sync]() 2025-04-05 10:30:12 +02:00
snps_udc_plat.c usb: Switch back to struct platform_driver::remove() 2024-10-04 15:13:03 +02:00
tegra-xudc.c usb: gadget: tegra-xudc: fix PM use count underflow 2025-08-13 17:15:45 +02:00
trace.c
trace.h tracing/treewide: Remove second parameter of __assign_str() 2024-05-22 20:14:47 -04:00
udc-xilinx.c usb: gadget: udc-xilinx: Use USB API functions rather than constants 2025-06-19 12:24:03 +02:00