Skip to content

Commit 6a5ad25

Browse files
committed
Bluetooth: ISO: Fix possible circular locking dependency
This attempts to fix the following trace: kworker/u3:1/184 is trying to acquire lock: ffff888001888130 (sk_lock-AF_BLUETOOTH-BTPROTO_ISO){+.+.}-{0:0}, at: iso_connect_cfm+0x2de/0x690 but task is already holding lock: ffff8880028d1c20 (&conn->lock){+.+.}-{2:2}, at: iso_connect_cfm+0x265/0x690 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&conn->lock){+.+.}-{2:2}: lock_acquire+0x176/0x3d0 _raw_spin_lock+0x2a/0x40 __iso_sock_close+0x1dd/0x4f0 iso_sock_release+0xa0/0x1b0 sock_close+0x5e/0x120 __fput+0x102/0x410 task_work_run+0xf1/0x160 exit_to_user_mode_prepare+0x170/0x180 syscall_exit_to_user_mode+0x19/0x50 do_syscall_64+0x4e/0x90 entry_SYSCALL_64_after_hwframe+0x62/0xcc -> #0 (sk_lock-AF_BLUETOOTH-BTPROTO_ISO){+.+.}-{0:0}: check_prev_add+0xfc/0x1190 __lock_acquire+0x1e27/0x2750 lock_acquire+0x176/0x3d0 lock_sock_nested+0x32/0x80 iso_connect_cfm+0x2de/0x690 hci_cc_le_setup_iso_path+0x195/0x340 hci_cmd_complete_evt+0x1ae/0x500 hci_event_packet+0x38e/0x7c0 hci_rx_work+0x34c/0x980 process_one_work+0x5a5/0x9a0 worker_thread+0x89/0x6f0 kthread+0x14e/0x180 ret_from_fork+0x22/0x30 other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&conn->lock); lock(sk_lock-AF_BLUETOOTH-BTPROTO_ISO); lock(&conn->lock); lock(sk_lock-AF_BLUETOOTH-BTPROTO_ISO); *** DEADLOCK *** Fixes: ccf74f2 ("Bluetooth: Add BTPROTO_ISO socket type") Fixes: f764a6c ("Bluetooth: ISO: Add broadcast support") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
1 parent 1ed8b37 commit 6a5ad25

File tree

1 file changed

+26
-35
lines changed

1 file changed

+26
-35
lines changed

net/bluetooth/iso.c

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -289,15 +289,15 @@ static int iso_connect_bis(struct sock *sk)
289289
hci_dev_unlock(hdev);
290290
hci_dev_put(hdev);
291291

292+
err = iso_chan_add(conn, sk, NULL);
293+
if (err)
294+
return err;
295+
292296
lock_sock(sk);
293297

294298
/* Update source addr of the socket */
295299
bacpy(&iso_pi(sk)->src, &hcon->src);
296300

297-
err = iso_chan_add(conn, sk, NULL);
298-
if (err)
299-
goto release;
300-
301301
if (hcon->state == BT_CONNECTED) {
302302
iso_sock_clear_timer(sk);
303303
sk->sk_state = BT_CONNECTED;
@@ -306,7 +306,6 @@ static int iso_connect_bis(struct sock *sk)
306306
iso_sock_set_timer(sk, sk->sk_sndtimeo);
307307
}
308308

309-
release:
310309
release_sock(sk);
311310
return err;
312311

@@ -372,15 +371,15 @@ static int iso_connect_cis(struct sock *sk)
372371
hci_dev_unlock(hdev);
373372
hci_dev_put(hdev);
374373

374+
err = iso_chan_add(conn, sk, NULL);
375+
if (err)
376+
return err;
377+
375378
lock_sock(sk);
376379

377380
/* Update source addr of the socket */
378381
bacpy(&iso_pi(sk)->src, &hcon->src);
379382

380-
err = iso_chan_add(conn, sk, NULL);
381-
if (err)
382-
goto release;
383-
384383
if (hcon->state == BT_CONNECTED) {
385384
iso_sock_clear_timer(sk);
386385
sk->sk_state = BT_CONNECTED;
@@ -392,7 +391,6 @@ static int iso_connect_cis(struct sock *sk)
392391
iso_sock_set_timer(sk, sk->sk_sndtimeo);
393392
}
394393

395-
release:
396394
release_sock(sk);
397395
return err;
398396

@@ -1432,64 +1430,59 @@ static void iso_conn_ready(struct iso_conn *conn)
14321430
struct sock *parent;
14331431
struct sock *sk = conn->sk;
14341432
struct hci_ev_le_big_sync_estabilished *ev;
1433+
struct hci_conn *hcon;
14351434

14361435
BT_DBG("conn %p", conn);
14371436

14381437
if (sk) {
14391438
iso_sock_ready(conn->sk);
14401439
} else {
1441-
iso_conn_lock(conn);
1442-
1443-
if (!conn->hcon) {
1444-
iso_conn_unlock(conn);
1440+
hcon = conn->hcon;
1441+
if (!hcon)
14451442
return;
1446-
}
14471443

1448-
ev = hci_recv_event_data(conn->hcon->hdev,
1444+
ev = hci_recv_event_data(hcon->hdev,
14491445
HCI_EVT_LE_BIG_SYNC_ESTABILISHED);
14501446
if (ev)
1451-
parent = iso_get_sock_listen(&conn->hcon->src,
1452-
&conn->hcon->dst,
1447+
parent = iso_get_sock_listen(&hcon->src,
1448+
&hcon->dst,
14531449
iso_match_big, ev);
14541450
else
1455-
parent = iso_get_sock_listen(&conn->hcon->src,
1451+
parent = iso_get_sock_listen(&hcon->src,
14561452
BDADDR_ANY, NULL, NULL);
14571453

1458-
if (!parent) {
1459-
iso_conn_unlock(conn);
1454+
if (!parent)
14601455
return;
1461-
}
14621456

14631457
lock_sock(parent);
14641458

14651459
sk = iso_sock_alloc(sock_net(parent), NULL,
14661460
BTPROTO_ISO, GFP_ATOMIC, 0);
14671461
if (!sk) {
14681462
release_sock(parent);
1469-
iso_conn_unlock(conn);
14701463
return;
14711464
}
14721465

14731466
iso_sock_init(sk, parent);
14741467

1475-
bacpy(&iso_pi(sk)->src, &conn->hcon->src);
1476-
iso_pi(sk)->src_type = conn->hcon->src_type;
1468+
bacpy(&iso_pi(sk)->src, &hcon->src);
1469+
iso_pi(sk)->src_type = hcon->src_type;
14771470

14781471
/* If hcon has no destination address (BDADDR_ANY) it means it
14791472
* was created by HCI_EV_LE_BIG_SYNC_ESTABILISHED so we need to
14801473
* initialize using the parent socket destination address.
14811474
*/
1482-
if (!bacmp(&conn->hcon->dst, BDADDR_ANY)) {
1483-
bacpy(&conn->hcon->dst, &iso_pi(parent)->dst);
1484-
conn->hcon->dst_type = iso_pi(parent)->dst_type;
1485-
conn->hcon->sync_handle = iso_pi(parent)->sync_handle;
1475+
if (!bacmp(&hcon->dst, BDADDR_ANY)) {
1476+
bacpy(&hcon->dst, &iso_pi(parent)->dst);
1477+
hcon->dst_type = iso_pi(parent)->dst_type;
1478+
hcon->sync_handle = iso_pi(parent)->sync_handle;
14861479
}
14871480

1488-
bacpy(&iso_pi(sk)->dst, &conn->hcon->dst);
1489-
iso_pi(sk)->dst_type = conn->hcon->dst_type;
1481+
bacpy(&iso_pi(sk)->dst, &hcon->dst);
1482+
iso_pi(sk)->dst_type = hcon->dst_type;
14901483

1491-
hci_conn_hold(conn->hcon);
1492-
__iso_chan_add(conn, sk, parent);
1484+
hci_conn_hold(hcon);
1485+
iso_chan_add(conn, sk, parent);
14931486

14941487
if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
14951488
sk->sk_state = BT_CONNECT2;
@@ -1500,8 +1493,6 @@ static void iso_conn_ready(struct iso_conn *conn)
15001493
parent->sk_data_ready(parent);
15011494

15021495
release_sock(parent);
1503-
1504-
iso_conn_unlock(conn);
15051496
}
15061497
}
15071498

0 commit comments

Comments
 (0)