diff options
author | Mat Martineau <mathewm@codeaurora.org> | 2012-04-27 19:50:50 -0400 |
---|---|---|
committer | Gustavo Padovan <gustavo@padovan.org> | 2012-05-09 00:40:49 -0400 |
commit | 61d6ef3e3408cdf7e622646fb90a9f7f9560b943 (patch) | |
tree | b8a711d6cb948ec81749aa8b06a53a8e2dac0b37 /net/bluetooth/l2cap_sock.c | |
parent | dbd89fddc1f1fc96085deb164b7b9b2361241dd3 (diff) |
Bluetooth: Make better use of l2cap_chan reference counting
L2CAP sockets contain a pointer to l2cap_chan that needs to be
reference counted in order to prevent a possible dangling pointer when
the channel is freed.
There were a few other cases where an l2cap_chan pointer on the stack
was dereferenced after a call to l2cap_chan_del. Those pointers are
also now reference counted.
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
Signed-off-by: Gustavo Padovan <gustavo@padovan.org>
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 2b5e7e81c3c0..6bf8ff75d95f 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -956,6 +956,7 @@ static void l2cap_sock_destruct(struct sock *sk) | |||
956 | { | 956 | { |
957 | BT_DBG("sk %p", sk); | 957 | BT_DBG("sk %p", sk); |
958 | 958 | ||
959 | l2cap_chan_put(l2cap_pi(sk)->chan); | ||
959 | if (l2cap_pi(sk)->rx_busy_skb) { | 960 | if (l2cap_pi(sk)->rx_busy_skb) { |
960 | kfree_skb(l2cap_pi(sk)->rx_busy_skb); | 961 | kfree_skb(l2cap_pi(sk)->rx_busy_skb); |
961 | l2cap_pi(sk)->rx_busy_skb = NULL; | 962 | l2cap_pi(sk)->rx_busy_skb = NULL; |
@@ -1057,6 +1058,8 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p | |||
1057 | return NULL; | 1058 | return NULL; |
1058 | } | 1059 | } |
1059 | 1060 | ||
1061 | l2cap_chan_hold(chan); | ||
1062 | |||
1060 | chan->sk = sk; | 1063 | chan->sk = sk; |
1061 | 1064 | ||
1062 | l2cap_pi(sk)->chan = chan; | 1065 | l2cap_pi(sk)->chan = chan; |