Skip to content

Commit

Permalink
Bluetooth: af_bluetooth: Fix Use-After-Free in bt_sock_recvmsg
Browse files Browse the repository at this point in the history
This can cause a race with bt_sock_ioctl() because
bt_sock_recvmsg() gets the skb from sk->sk_receive_queue
and then frees it without holding lock_sock.
A use-after-free for a skb occurs with the following flow.
```
bt_sock_recvmsg() -> skb_recv_datagram() -> skb_free_datagram()
bt_sock_ioctl() -> skb_peek()
```
Add lock_sock to bt_sock_recvmsg() to fix this issue.

Cc: [email protected]
Fixes: 1da177e ("Linux-2.6.12-rc2")
Signed-off-by: Hyunwoo Kim <[email protected]>
Signed-off-by: Luiz Augusto von Dentz <[email protected]>
  • Loading branch information
V4bel-theori authored and Vudentz committed Dec 15, 2023
1 parent 04a342c commit 2e07e83
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion net/bluetooth/af_bluetooth.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,11 +309,14 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
if (flags & MSG_OOB)
return -EOPNOTSUPP;

lock_sock(sk);

skb = skb_recv_datagram(sk, flags, &err);
if (!skb) {
if (sk->sk_shutdown & RCV_SHUTDOWN)
return 0;
err = 0;

release_sock(sk);
return err;
}

Expand Down Expand Up @@ -343,6 +346,8 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,

skb_free_datagram(sk, skb);

release_sock(sk);

if (flags & MSG_TRUNC)
copied = skblen;

Expand Down

0 comments on commit 2e07e83

Please sign in to comment.