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 /net/bluetooth | |
parent | 8c1d787be4b62d2d1b6f04953eca4bcf7c839d44 (diff) | |
download | op-kernel-dev-6ff5abbf4e4aa88feb9c2367d4fbd9ea081bf98c.zip op-kernel-dev-6ff5abbf4e4aa88feb9c2367d4fbd9ea081bf98c.tar.gz |
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>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/l2cap_core.c | 10 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 2 |
2 files changed, 8 insertions, 4 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 8562ac1..338d8c3 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 61d93f6..0e23ebd 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); |