[PATCH] L2CAP: Fix null-ptr-deref in l2cap_sock_set_shutdown_cb

From: Sungwoo Kim
Date: Wed Jan 18 2023 - 20:38:01 EST


The L2CAP socket shutdown invokes l2cap_sock_destruct without a lock
on conn->chan_lock, assigning NULL to chan->data *just before*
the l2cap_disconnect_req thread that accesses to chan->data.
This patch prevent it by adding a null check for a workaround, instead
of fixing a lock.

This bug is found by FuzzBT, a modified Syzkaller by Sungwoo Kim(me).
Ruoyu Wu(wuruoyu@xxxxxx) and Hui Peng(benquike@xxxxxxxxx) has helped
the FuzzBT project.

Signed-off-by: Sungwoo Kim <iam@xxxxxxxxxxxx>
---
net/bluetooth/l2cap_sock.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index ca8f07f35..350c7afdf 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1681,9 +1681,11 @@ static void l2cap_sock_set_shutdown_cb(struct l2cap_chan *chan)
{
struct sock *sk = chan->data;

- lock_sock(sk);
- sk->sk_shutdown = SHUTDOWN_MASK;
- release_sock(sk);
+ if (!sk) {
+ lock_sock(sk);
+ sk->sk_shutdown = SHUTDOWN_MASK;
+ release_sock(sk);
+ }
}

static long l2cap_sock_get_sndtimeo_cb(struct l2cap_chan *chan)
--
2.25.1