aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>2012-02-24 09:35:32 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-24 13:32:50 -0500
commit5b4cedaa14bd1fe3ca1d59c684203a6ae7747faa (patch)
tree141f050917807340e65bf5a9236d01fb5ae08755 /net
parent8a7a3fd680f3ea9f22fc504caf5e8e056a800401 (diff)
Bluetooth: Fix double locking in LE and conless chan
Remove socket lock since chan->ops->recv locks socket itself. Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com> Reviewed-by: Ulisses Furquim <ulisses@profusion.mobi> Acked-by: Gustavo F. Padovan <padovan@profusion.mobi> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/l2cap_core.c24
1 files changed, 4 insertions, 20 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 5f4cfea33915..db04c9e4e1d9 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4369,18 +4369,13 @@ done:
4369 4369
4370static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb) 4370static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
4371{ 4371{
4372 struct sock *sk = NULL;
4373 struct l2cap_chan *chan; 4372 struct l2cap_chan *chan;
4374 4373
4375 chan = l2cap_global_chan_by_psm(0, psm, conn->src); 4374 chan = l2cap_global_chan_by_psm(0, psm, conn->src);
4376 if (!chan) 4375 if (!chan)
4377 goto drop; 4376 goto drop;
4378 4377
4379 sk = chan->sk; 4378 BT_DBG("chan %p, len %d", chan, skb->len);
4380
4381 lock_sock(sk);
4382
4383 BT_DBG("sk %p, len %d", sk, skb->len);
4384 4379
4385 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED) 4380 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
4386 goto drop; 4381 goto drop;
@@ -4389,31 +4384,23 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
4389 goto drop; 4384 goto drop;
4390 4385
4391 if (!chan->ops->recv(chan->data, skb)) 4386 if (!chan->ops->recv(chan->data, skb))
4392 goto done; 4387 return 0;
4393 4388
4394drop: 4389drop:
4395 kfree_skb(skb); 4390 kfree_skb(skb);
4396 4391
4397done:
4398 if (sk)
4399 release_sock(sk);
4400 return 0; 4392 return 0;
4401} 4393}
4402 4394
4403static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct sk_buff *skb) 4395static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct sk_buff *skb)
4404{ 4396{
4405 struct sock *sk = NULL;
4406 struct l2cap_chan *chan; 4397 struct l2cap_chan *chan;
4407 4398
4408 chan = l2cap_global_chan_by_scid(0, cid, conn->src); 4399 chan = l2cap_global_chan_by_scid(0, cid, conn->src);
4409 if (!chan) 4400 if (!chan)
4410 goto drop; 4401 goto drop;
4411 4402
4412 sk = chan->sk; 4403 BT_DBG("chan %p, len %d", chan, skb->len);
4413
4414 lock_sock(sk);
4415
4416 BT_DBG("sk %p, len %d", sk, skb->len);
4417 4404
4418 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED) 4405 if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
4419 goto drop; 4406 goto drop;
@@ -4422,14 +4409,11 @@ static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct
4422 goto drop; 4409 goto drop;
4423 4410
4424 if (!chan->ops->recv(chan->data, skb)) 4411 if (!chan->ops->recv(chan->data, skb))
4425 goto done; 4412 return 0;
4426 4413
4427drop: 4414drop:
4428 kfree_skb(skb); 4415 kfree_skb(skb);
4429 4416
4430done:
4431 if (sk)
4432 release_sock(sk);
4433 return 0; 4417 return 0;
4434} 4418}
4435 4419