Bluetooth: Lock the L2CAP channel when sending
The ERTM and streaming mode transmit queue must only be accessed while the L2CAP channel lock is held. Locking the channel before calling l2cap_chan_send ensures that multiple threads cannot simultaneously manipulate the queue when sending and receiving concurrently. L2CAP channel locking had previously moved to the l2cap_chan struct instead of the associated socket, so some of the old socket locking can also be removed in this patch. Signed-off-by: Mat Martineau <mathewm@codeaurora.org> Signed-off-by: Gustavo Padovan <gustavo@padovan.org>
This commit is contained in:
parent
ef191aded5
commit
a6a5568c03
@ -257,12 +257,10 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk,
|
|||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
release_sock(sk);
|
|
||||||
if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) {
|
if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) {
|
||||||
skb_reserve(skb, BT_SKB_RESERVE);
|
skb_reserve(skb, BT_SKB_RESERVE);
|
||||||
bt_cb(skb)->incoming = 0;
|
bt_cb(skb)->incoming = 0;
|
||||||
}
|
}
|
||||||
lock_sock(sk);
|
|
||||||
|
|
||||||
if (!skb && *err)
|
if (!skb && *err)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -720,16 +720,13 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
|
|||||||
if (msg->msg_flags & MSG_OOB)
|
if (msg->msg_flags & MSG_OOB)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
lock_sock(sk);
|
if (sk->sk_state != BT_CONNECTED)
|
||||||
|
|
||||||
if (sk->sk_state != BT_CONNECTED) {
|
|
||||||
release_sock(sk);
|
|
||||||
return -ENOTCONN;
|
return -ENOTCONN;
|
||||||
}
|
|
||||||
|
|
||||||
|
l2cap_chan_lock(chan);
|
||||||
err = l2cap_chan_send(chan, msg, len, sk->sk_priority);
|
err = l2cap_chan_send(chan, msg, len, sk->sk_priority);
|
||||||
|
l2cap_chan_unlock(chan);
|
||||||
|
|
||||||
release_sock(sk);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -940,7 +937,10 @@ static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
|
|||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
l2cap_chan_unlock(chan);
|
||||||
skb = bt_skb_send_alloc(chan->sk, len, nb, &err);
|
skb = bt_skb_send_alloc(chan->sk, len, nb, &err);
|
||||||
|
l2cap_chan_lock(chan);
|
||||||
|
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user