Merge tag 'for_v5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
[linux-2.6-microblaze.git] / net / bluetooth / l2cap_sock.c
index e1a3e66..f1b1edd 100644 (file)
@@ -1521,8 +1521,6 @@ static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err)
 
        parent = bt_sk(sk)->parent;
 
-       sock_set_flag(sk, SOCK_ZAPPED);
-
        switch (chan->state) {
        case BT_OPEN:
        case BT_BOUND:
@@ -1549,8 +1547,11 @@ static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err)
 
                break;
        }
-
        release_sock(sk);
+
+       /* Only zap after cleanup to avoid use after free race */
+       sock_set_flag(sk, SOCK_ZAPPED);
+
 }
 
 static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,
@@ -1663,6 +1664,19 @@ static void l2cap_sock_suspend_cb(struct l2cap_chan *chan)
        sk->sk_state_change(sk);
 }
 
+static int l2cap_sock_filter(struct l2cap_chan *chan, struct sk_buff *skb)
+{
+       struct sock *sk = chan->data;
+
+       switch (chan->mode) {
+       case L2CAP_MODE_ERTM:
+       case L2CAP_MODE_STREAMING:
+               return sk_filter(sk, skb);
+       }
+
+       return 0;
+}
+
 static const struct l2cap_ops l2cap_chan_ops = {
        .name                   = "L2CAP Socket Interface",
        .new_connection         = l2cap_sock_new_connection_cb,
@@ -1678,6 +1692,7 @@ static const struct l2cap_ops l2cap_chan_ops = {
        .get_sndtimeo           = l2cap_sock_get_sndtimeo_cb,
        .get_peer_pid           = l2cap_sock_get_peer_pid_cb,
        .alloc_skb              = l2cap_sock_alloc_skb_cb,
+       .filter                 = l2cap_sock_filter,
 };
 
 static void l2cap_sock_destruct(struct sock *sk)