In the Linux kernel, the following vulnerability has been resolved:
Bluetooth: avoid deadlock between hci_dev->lock and socket lock
Commit eab2404ba798 ("Bluetooth: Add BTPHY socket option") added a dependency between socket lock and hcidev->lock that could lead to deadlock.
It turns out that hciconnget_phy() is not in any way relying on hdev being immutable during the runtime of this function, neither does it even look at any of the members of hdev, and as such there is no need to hold that lock.
This fixes the lockdep splat below:
====================================================== WARNING: possible circular locking dependency detected 5.12.0-rc1-00026-g73d464503354 #10 Not tainted
bluetoothd/1118 is trying to acquire lock: ffff8f078383c078 (&hdev->lock){+.+.}-{3:3}, at: hciconnget_phy+0x1c/0x150 [bluetooth]
but task is already holding lock: ffff8f07e831d920 (sklock-AFBLUETOOTH-BTPROTOL2CAP){+.+.}-{0:0}, at: l2capsock_getsockopt+0x8b/0x610
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #3 (sklock-AFBLUETOOTH-BTPROTOL2CAP){+.+.}-{0:0}: locksocknested+0x72/0xa0 l2capsockreadycb+0x18/0x70 [bluetooth] l2capconfigrsp+0x27a/0x520 [bluetooth] l2capsigchannel+0x658/0x1330 [bluetooth] l2caprecvframe+0x1ba/0x310 [bluetooth] hcirxwork+0x1cc/0x640 [bluetooth] processonework+0x244/0x5f0 workerthread+0x3c/0x380 kthread+0x13e/0x160 retfrom_fork+0x22/0x30
-> #2 (&chan->lock#2/1){+.+.}-{3:3}: _mutexlock+0xa3/0xa10 l2capchanconnect+0x33a/0x940 [bluetooth] l2capsockconnect+0x141/0x2a0 [bluetooth] _sysconnect+0x9b/0xc0 _x64sysconnect+0x16/0x20 dosyscall64+0x33/0x80 entrySYSCALL64after_hwframe+0x44/0xae
-> #1 (&conn->chanlock){+.+.}-{3:3}: _mutexlock+0xa3/0xa10 l2capchanconnect+0x322/0x940 [bluetooth] l2capsockconnect+0x141/0x2a0 [bluetooth] _sysconnect+0x9b/0xc0 _x64sysconnect+0x16/0x20 dosyscall64+0x33/0x80 entrySYSCALL64afterhwframe+0x44/0xae
-> #0 (&hdev->lock){+.+.}-{3:3}: _lockacquire+0x147a/0x1a50 lockacquire+0x277/0x3d0 _mutexlock+0xa3/0xa10 hciconngetphy+0x1c/0x150 [bluetooth] l2capsockgetsockopt+0x5a9/0x610 [bluetooth] _sysgetsockopt+0xcc/0x200 _x64sysgetsockopt+0x20/0x30 dosyscall64+0x33/0x80 entrySYSCALL64after_hwframe+0x44/0xae
other info that might help us debug this:
Chain exists of: &hdev->lock --> &chan->lock#2/1 --> sklock-AFBLUETOOTH-BTPROTO_L2CAP
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(sklock-AFBLUETOOTH-BTPROTOL2CAP); lock(&chan->lock#2/1); lock(sklock-AFBLUETOOTH-BTPROTOL2CAP); lock(&hdev->lock);
* DEADLOCK *
1 lock held by bluetoothd/1118: #0: ffff8f07e831d920 (sklock-AFBLUETOOTH-BTPROTOL2CAP){+.+.}-{0:0}, at: l2capsock_getsockopt+0x8b/0x610 [bluetooth]
stack backtrace: CPU: 3 PID: 1118 Comm: bluetoothd Not tainted 5.12.0-rc1-00026-g73d464503354 #10 Hardware name: LENOVO 20K5S22R00/20K5S22R00, BIOS R0IET38W (1.16 ) 05/31/2017 Call Trace: dumpstack+0x7f/0xa1 checknoncircular+0x105/0x120 ? _lockacquire+0x147a/0x1a50 _lockacquire+0x147a/0x1a50 lockacquire+0x277/0x3d0 ? hciconngetphy+0x1c/0x150 [bluetooth] ? _lockacquire+0x2e1/0x1a50 ? lockisheldtype+0xb4/0x120 ? hciconngetphy+0x1c/0x150 [bluetooth] _mutexlock+0xa3/0xa10 ? hciconngetphy+0x1c/0x150 [bluetooth] ? lockacquire+0x277/0x3d0 ? markheldlocks+0x49/0x70 ? markheldlocks+0x49/0x70 ? hciconngetphy+0x1c/0x150 [bluetooth] hciconngetphy+0x ---truncated---