Skip to content

Commit 0baecef

Browse files
iulia-tanasescusmb49
authored andcommitted
Bluetooth: iso: Fix circular lock in iso_conn_big_sync
BugLink: https://bugs.launchpad.net/bugs/2101915 [ Upstream commit 7a17308c17880d259105f6e591eb1bc77b9612f0 ] This fixes the circular locking dependency warning below, by reworking iso_sock_recvmsg, to ensure that the socket lock is always released before calling a function that locks hdev. [ 561.670344] ====================================================== [ 561.670346] WARNING: possible circular locking dependency detected [ 561.670349] 6.12.0-rc6+ #26 Not tainted [ 561.670351] ------------------------------------------------------ [ 561.670353] iso-tester/3289 is trying to acquire lock: [ 561.670355] ffff88811f600078 (&hdev->lock){+.+.}-{3:3}, at: iso_conn_big_sync+0x73/0x260 [bluetooth] [ 561.670405] but task is already holding lock: [ 561.670407] ffff88815af58258 (sk_lock-AF_BLUETOOTH){+.+.}-{0:0}, at: iso_sock_recvmsg+0xbf/0x500 [bluetooth] [ 561.670450] which lock already depends on the new lock. [ 561.670452] the existing dependency chain (in reverse order) is: [ 561.670453] -> #2 (sk_lock-AF_BLUETOOTH){+.+.}-{0:0}: [ 561.670458] lock_acquire+0x7c/0xc0 [ 561.670463] lock_sock_nested+0x3b/0xf0 [ 561.670467] bt_accept_dequeue+0x1a5/0x4d0 [bluetooth] [ 561.670510] iso_sock_accept+0x271/0x830 [bluetooth] [ 561.670547] do_accept+0x3dd/0x610 [ 561.670550] __sys_accept4+0xd8/0x170 [ 561.670553] __x64_sys_accept+0x74/0xc0 [ 561.670556] x64_sys_call+0x17d6/0x25f0 [ 561.670559] do_syscall_64+0x87/0x150 [ 561.670563] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 561.670567] -> #1 (sk_lock-AF_BLUETOOTH-BTPROTO_ISO){+.+.}-{0:0}: [ 561.670571] lock_acquire+0x7c/0xc0 [ 561.670574] lock_sock_nested+0x3b/0xf0 [ 561.670577] iso_sock_listen+0x2de/0xf30 [bluetooth] [ 561.670617] __sys_listen_socket+0xef/0x130 [ 561.670620] __x64_sys_listen+0xe1/0x190 [ 561.670623] x64_sys_call+0x2517/0x25f0 [ 561.670626] do_syscall_64+0x87/0x150 [ 561.670629] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 561.670632] -> #0 (&hdev->lock){+.+.}-{3:3}: [ 561.670636] __lock_acquire+0x32ad/0x6ab0 [ 561.670639] lock_acquire.part.0+0x118/0x360 [ 561.670642] lock_acquire+0x7c/0xc0 [ 561.670644] __mutex_lock+0x18d/0x12f0 [ 561.670647] mutex_lock_nested+0x1b/0x30 [ 561.670651] iso_conn_big_sync+0x73/0x260 [bluetooth] [ 561.670687] iso_sock_recvmsg+0x3e9/0x500 [bluetooth] [ 561.670722] sock_recvmsg+0x1d5/0x240 [ 561.670725] sock_read_iter+0x27d/0x470 [ 561.670727] vfs_read+0x9a0/0xd30 [ 561.670731] ksys_read+0x1a8/0x250 [ 561.670733] __x64_sys_read+0x72/0xc0 [ 561.670736] x64_sys_call+0x1b12/0x25f0 [ 561.670738] do_syscall_64+0x87/0x150 [ 561.670741] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 561.670744] other info that might help us debug this: [ 561.670745] Chain exists of: &hdev->lock --> sk_lock-AF_BLUETOOTH-BTPROTO_ISO --> sk_lock-AF_BLUETOOTH [ 561.670751] Possible unsafe locking scenario: [ 561.670753] CPU0 CPU1 [ 561.670754] ---- ---- [ 561.670756] lock(sk_lock-AF_BLUETOOTH); [ 561.670758] lock(sk_lock AF_BLUETOOTH-BTPROTO_ISO); [ 561.670761] lock(sk_lock-AF_BLUETOOTH); [ 561.670764] lock(&hdev->lock); [ 561.670767] *** DEADLOCK *** Fixes: 07a9342b94a9 ("Bluetooth: ISO: Send BIG Create Sync via hci_sync") Signed-off-by: Iulia Tanasescu <iulia.tanasescu@nxp.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org> (cherry picked from commit cbe640d6cae590b9a7d81ce86fe9a90e83eec1d5 linux-6.12.y) [koichiroden: follow-up fix from v6.12.6] Signed-off-by: Koichiro Den <koichiro.den@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
1 parent 396ce4a commit 0baecef

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

net/bluetooth/iso.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,6 +1398,7 @@ static void iso_conn_big_sync(struct sock *sk)
13981398
* change.
13991399
*/
14001400
hci_dev_lock(hdev);
1401+
lock_sock(sk);
14011402

14021403
if (!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
14031404
err = hci_le_big_create_sync(hdev, iso_pi(sk)->conn->hcon,
@@ -1410,6 +1411,7 @@ static void iso_conn_big_sync(struct sock *sk)
14101411
err);
14111412
}
14121413

1414+
release_sock(sk);
14131415
hci_dev_unlock(hdev);
14141416
}
14151417

@@ -1418,39 +1420,57 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
14181420
{
14191421
struct sock *sk = sock->sk;
14201422
struct iso_pinfo *pi = iso_pi(sk);
1423+
bool early_ret = false;
1424+
int err = 0;
14211425

14221426
BT_DBG("sk %p", sk);
14231427

14241428
if (test_and_clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
1429+
sock_hold(sk);
14251430
lock_sock(sk);
1431+
14261432
switch (sk->sk_state) {
14271433
case BT_CONNECT2:
14281434
if (test_bit(BT_SK_PA_SYNC, &pi->flags)) {
1435+
release_sock(sk);
14291436
iso_conn_big_sync(sk);
1437+
lock_sock(sk);
1438+
14301439
sk->sk_state = BT_LISTEN;
14311440
} else {
14321441
iso_conn_defer_accept(pi->conn->hcon);
14331442
sk->sk_state = BT_CONFIG;
14341443
}
1435-
release_sock(sk);
1436-
return 0;
1444+
1445+
early_ret = true;
1446+
break;
14371447
case BT_CONNECTED:
14381448
if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) {
1449+
release_sock(sk);
14391450
iso_conn_big_sync(sk);
1451+
lock_sock(sk);
1452+
14401453
sk->sk_state = BT_LISTEN;
1441-
release_sock(sk);
1442-
return 0;
1454+
early_ret = true;
14431455
}
14441456

1445-
release_sock(sk);
14461457
break;
14471458
case BT_CONNECT:
14481459
release_sock(sk);
1449-
return iso_connect_cis(sk);
1460+
err = iso_connect_cis(sk);
1461+
lock_sock(sk);
1462+
1463+
early_ret = true;
1464+
break;
14501465
default:
1451-
release_sock(sk);
14521466
break;
14531467
}
1468+
1469+
release_sock(sk);
1470+
sock_put(sk);
1471+
1472+
if (early_ret)
1473+
return err;
14541474
}
14551475

14561476
return bt_sock_recvmsg(sock, msg, len, flags);

0 commit comments

Comments
 (0)