Skip to content

Commit

Permalink
Bluetooth: Lock the L2CAP channel when sending
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mat Martineau authored and Gustavo Padovan committed May 16, 2012
1 parent ef191ad commit a6a5568
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 8 deletions.
2 changes: 0 additions & 2 deletions include/net/bluetooth/bluetooth.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,12 +257,10 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk,
{
struct sk_buff *skb;

release_sock(sk);
if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) {
skb_reserve(skb, BT_SKB_RESERVE);
bt_cb(skb)->incoming = 0;
}
lock_sock(sk);

if (!skb && *err)
return NULL;
Expand Down
12 changes: 6 additions & 6 deletions net/bluetooth/l2cap_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,16 +720,13 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
if (msg->msg_flags & MSG_OOB)
return -EOPNOTSUPP;

lock_sock(sk);

if (sk->sk_state != BT_CONNECTED) {
release_sock(sk);
if (sk->sk_state != BT_CONNECTED)
return -ENOTCONN;
}

l2cap_chan_lock(chan);
err = l2cap_chan_send(chan, msg, len, sk->sk_priority);
l2cap_chan_unlock(chan);

release_sock(sk);
return err;
}

Expand Down Expand Up @@ -940,7 +937,10 @@ static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
struct sk_buff *skb;
int err;

l2cap_chan_unlock(chan);
skb = bt_skb_send_alloc(chan->sk, len, nb, &err);
l2cap_chan_lock(chan);

if (!skb)
return ERR_PTR(err);

Expand Down

0 comments on commit a6a5568

Please sign in to comment.