Skip to content

Commit cad0944

Browse files
committed
Bluetooth: af_bluetooth: Fix deadlock
jira LE-3201 Rebuild_History Non-Buildable kernel-rt-4.18.0-553.30.1.rt7.371.el8_10 commit-author Luiz Augusto von Dentz <[email protected]> commit f7b94bd Attemting to do sock_lock on .recvmsg may cause a deadlock as shown bellow, so instead of using sock_sock this uses sk_receive_queue.lock on bt_sock_ioctl to avoid the UAF: INFO: task kworker/u9:1:121 blocked for more than 30 seconds. Not tainted 6.7.6-lemon #183 Workqueue: hci0 hci_rx_work Call Trace: <TASK> __schedule+0x37d/0xa00 schedule+0x32/0xe0 __lock_sock+0x68/0xa0 ? __pfx_autoremove_wake_function+0x10/0x10 lock_sock_nested+0x43/0x50 l2cap_sock_recv_cb+0x21/0xa0 l2cap_recv_frame+0x55b/0x30a0 ? psi_task_switch+0xeb/0x270 ? finish_task_switch.isra.0+0x93/0x2a0 hci_rx_work+0x33a/0x3f0 process_one_work+0x13a/0x2f0 worker_thread+0x2f0/0x410 ? __pfx_worker_thread+0x10/0x10 kthread+0xe0/0x110 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x2c/0x50 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1b/0x30 </TASK> Fixes: 2e07e83 ("Bluetooth: af_bluetooth: Fix Use-After-Free in bt_sock_recvmsg") Signed-off-by: Luiz Augusto von Dentz <[email protected]> (cherry picked from commit f7b94bd) Signed-off-by: Jonathan Maple <[email protected]>
1 parent 1bc318c commit cad0944

File tree

1 file changed

+3
-7
lines changed

1 file changed

+3
-7
lines changed

net/bluetooth/af_bluetooth.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -262,14 +262,11 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
262262
if (flags & MSG_OOB)
263263
return -EOPNOTSUPP;
264264

265-
lock_sock(sk);
266-
267265
skb = skb_recv_datagram(sk, flags, &err);
268266
if (!skb) {
269267
if (sk->sk_shutdown & RCV_SHUTDOWN)
270268
err = 0;
271269

272-
release_sock(sk);
273270
return err;
274271
}
275272

@@ -295,8 +292,6 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
295292

296293
skb_free_datagram(sk, skb);
297294

298-
release_sock(sk);
299-
300295
if (flags & MSG_TRUNC)
301296
copied = skblen;
302297

@@ -519,10 +514,11 @@ int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
519514
if (sk->sk_state == BT_LISTEN)
520515
return -EINVAL;
521516

522-
lock_sock(sk);
517+
spin_lock(&sk->sk_receive_queue.lock);
523518
skb = skb_peek(&sk->sk_receive_queue);
524519
amount = skb ? skb->len : 0;
525-
release_sock(sk);
520+
spin_unlock(&sk->sk_receive_queue.lock);
521+
526522
err = put_user(amount, (int __user *)arg);
527523
break;
528524

0 commit comments

Comments
 (0)