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>
This commit is contained in:
@ -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);
|
void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err);
|
||||||
struct l2cap_chan *l2cap_chan_alloc(struct sock *sk);
|
struct l2cap_chan *l2cap_chan_alloc(struct sock *sk);
|
||||||
void l2cap_chan_del(struct l2cap_chan *chan, int err);
|
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);
|
int l2cap_chan_connect(struct l2cap_chan *chan);
|
||||||
|
|
||||||
#endif /* __L2CAP_H */
|
#endif /* __L2CAP_H */
|
||||||
|
@ -160,6 +160,11 @@ struct l2cap_chan *l2cap_chan_alloc(struct sock *sk)
|
|||||||
return chan;
|
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)
|
static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
|
||||||
{
|
{
|
||||||
struct sock *sk = chan->sk;
|
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 &&
|
if (!(chan->conf_state & L2CAP_CONF_OUTPUT_DONE &&
|
||||||
chan->conf_state & L2CAP_CONF_INPUT_DONE))
|
chan->conf_state & L2CAP_CONF_INPUT_DONE))
|
||||||
goto free;
|
return;
|
||||||
|
|
||||||
skb_queue_purge(&chan->tx_q);
|
skb_queue_purge(&chan->tx_q);
|
||||||
|
|
||||||
@ -255,9 +260,6 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
|
|||||||
kfree(l);
|
kfree(l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free:
|
|
||||||
kfree(chan);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
|
static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
|
||||||
|
@ -849,6 +849,8 @@ void l2cap_sock_kill(struct sock *sk)
|
|||||||
BT_DBG("sk %p state %d", sk, sk->sk_state);
|
BT_DBG("sk %p state %d", sk, sk->sk_state);
|
||||||
|
|
||||||
/* Kill poor orphan */
|
/* Kill poor orphan */
|
||||||
|
|
||||||
|
l2cap_chan_free(l2cap_pi(sk)->chan);
|
||||||
bt_sock_unlink(&l2cap_sk_list, sk);
|
bt_sock_unlink(&l2cap_sk_list, sk);
|
||||||
sock_set_flag(sk, SOCK_DEAD);
|
sock_set_flag(sk, SOCK_DEAD);
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
|
Reference in New Issue
Block a user