diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-04-25 15:10:41 -0300 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-04-28 01:10:01 -0300 |
commit | 6ff5abbf4e4aa88feb9c2367d4fbd9ea081bf98c (patch) | |
tree | 05848e91d3ac481432b3c0718dbb9fd91a5067c1 | |
parent | 8c1d787be4b62d2d1b6f04953eca4bcf7c839d44 (diff) |
Bluetooth: Fix memory leak with L2CAP channels
A new l2cap_chan_free() is added to free the channels.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r-- | include/net/bluetooth/l2cap.h | 1 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 10 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 2 |
3 files changed, 9 insertions, 4 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 3de90a91a4e..0a0134161b1 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -469,6 +469,7 @@ struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err); struct l2cap_chan *l2cap_chan_alloc(struct sock *sk); void l2cap_chan_del(struct l2cap_chan *chan, int err); +void l2cap_chan_free(struct l2cap_chan *chan); int l2cap_chan_connect(struct l2cap_chan *chan); #endif /* __L2CAP_H */ diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 8562ac1ba94..338d8c3eeda 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -160,6 +160,11 @@ struct l2cap_chan *l2cap_chan_alloc(struct sock *sk) return chan; } +void l2cap_chan_free(struct l2cap_chan *chan) +{ + kfree(chan); +} + static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) { struct sock *sk = chan->sk; @@ -236,7 +241,7 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) if (!(chan->conf_state & L2CAP_CONF_OUTPUT_DONE && chan->conf_state & L2CAP_CONF_INPUT_DONE)) - goto free; + return; skb_queue_purge(&chan->tx_q); @@ -255,9 +260,6 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) kfree(l); } } - -free: - kfree(chan); } static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 61d93f6c36c..0e23ebdf7c8 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -849,6 +849,8 @@ void l2cap_sock_kill(struct sock *sk) BT_DBG("sk %p state %d", sk, sk->sk_state); /* Kill poor orphan */ + + l2cap_chan_free(l2cap_pi(sk)->chan); bt_sock_unlink(&l2cap_sk_list, sk); sock_set_flag(sk, SOCK_DEAD); sock_put(sk); |