--- x/net/bluetooth/af_bluetooth.c +++ y/net/bluetooth/af_bluetooth.c @@ -256,6 +256,8 @@ void bt_accept_unlink(struct sock *sk) { BT_DBG("sk %p state %d", sk, sk->sk_state); + if (bt_sk(sk)->parent == NULL) + return; list_del_init(&bt_sk(sk)->accept_q); sk_acceptq_removed(bt_sk(sk)->parent); bt_sk(sk)->parent = NULL; --- x/net/bluetooth/l2cap_sock.c +++ y/net/bluetooth/l2cap_sock.c @@ -1581,6 +1581,7 @@ static void l2cap_sock_teardown_cb(struc if (!sk) return; + sock_hold(sk); BT_DBG("chan %p state %s", chan, state_to_string(chan->state)); @@ -1613,8 +1614,14 @@ static void l2cap_sock_teardown_cb(struc sk->sk_err = err; if (parent) { + sock_hold(parent); + release_sock(sk); + lock_sock(parent); bt_accept_unlink(sk); + release_sock(parent); parent->sk_data_ready(parent); + sock_put(parent); + goto zap; } else { sk->sk_state_change(sk); } @@ -1623,9 +1630,10 @@ static void l2cap_sock_teardown_cb(struc } release_sock(sk); +zap: /* Only zap after cleanup to avoid use after free race */ sock_set_flag(sk, SOCK_ZAPPED); - + sock_put(sk); } static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,