diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 6db60946c627..278cc4db922f 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1486,7 +1486,14 @@ static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) int err; lock_sock(sk); - + sock_hold(sk); + l2cap_chan_hold(chan); + l2cap_chan_lock(chan); + if (sock_flag(sk, SOCK_DEAD)) { + err = -ENXIO; + goto done; + } + if (chan->mode == L2CAP_MODE_ERTM && !list_empty(&pi->rx_busy)) { err = -ENOMEM; goto done; @@ -1534,7 +1541,11 @@ static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) } done: - release_sock(sk); + l2cap_chan_unlock(chan); + l2cap_chan_put(chan); + sock_put(sk); + if (err != -ENXIO) + release_sock(sk); return err; }