CVE-2022-49936
Publication date:
18/06/2025
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
USB: core: Prevent nested device-reset calls<br />
<br />
Automatic kernel fuzzing revealed a recursive locking violation in<br />
usb-storage:<br />
<br />
============================================<br />
WARNING: possible recursive locking detected<br />
5.18.0 #3 Not tainted<br />
--------------------------------------------<br />
kworker/1:3/1205 is trying to acquire lock:<br />
ffff888018638db8 (&us_interface_key[i]){+.+.}-{3:3}, at:<br />
usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230<br />
<br />
but task is already holding lock:<br />
ffff888018638db8 (&us_interface_key[i]){+.+.}-{3:3}, at:<br />
usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230<br />
<br />
...<br />
<br />
stack backtrace:<br />
CPU: 1 PID: 1205 Comm: kworker/1:3 Not tainted 5.18.0 #3<br />
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS<br />
1.13.0-1ubuntu1.1 04/01/2014<br />
Workqueue: usb_hub_wq hub_event<br />
Call Trace:<br />
<br />
__dump_stack lib/dump_stack.c:88 [inline]<br />
dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106<br />
print_deadlock_bug kernel/locking/lockdep.c:2988 [inline]<br />
check_deadlock kernel/locking/lockdep.c:3031 [inline]<br />
validate_chain kernel/locking/lockdep.c:3816 [inline]<br />
__lock_acquire.cold+0x152/0x3ca kernel/locking/lockdep.c:5053<br />
lock_acquire kernel/locking/lockdep.c:5665 [inline]<br />
lock_acquire+0x1ab/0x520 kernel/locking/lockdep.c:5630<br />
__mutex_lock_common kernel/locking/mutex.c:603 [inline]<br />
__mutex_lock+0x14f/0x1610 kernel/locking/mutex.c:747<br />
usb_stor_pre_reset+0x35/0x40 drivers/usb/storage/usb.c:230<br />
usb_reset_device+0x37d/0x9a0 drivers/usb/core/hub.c:6109<br />
r871xu_dev_remove+0x21a/0x270 drivers/staging/rtl8712/usb_intf.c:622<br />
usb_unbind_interface+0x1bd/0x890 drivers/usb/core/driver.c:458<br />
device_remove drivers/base/dd.c:545 [inline]<br />
device_remove+0x11f/0x170 drivers/base/dd.c:537<br />
__device_release_driver drivers/base/dd.c:1222 [inline]<br />
device_release_driver_internal+0x1a7/0x2f0 drivers/base/dd.c:1248<br />
usb_driver_release_interface+0x102/0x180 drivers/usb/core/driver.c:627<br />
usb_forced_unbind_intf+0x4d/0xa0 drivers/usb/core/driver.c:1118<br />
usb_reset_device+0x39b/0x9a0 drivers/usb/core/hub.c:6114<br />
<br />
This turned out not to be an error in usb-storage but rather a nested<br />
device reset attempt. That is, as the rtl8712 driver was being<br />
unbound from a composite device in preparation for an unrelated USB<br />
reset (that driver does not have pre_reset or post_reset callbacks),<br />
its ->remove routine called usb_reset_device() -- thus nesting one<br />
reset call within another.<br />
<br />
Performing a reset as part of disconnect processing is a questionable<br />
practice at best. However, the bug report points out that the USB<br />
core does not have any protection against nested resets. Adding a<br />
reset_in_progress flag and testing it will prevent such errors in the<br />
future.
Severity CVSS v4.0: Pending analysis
Last modification:
18/06/2025