forked from Minki/linux
net: diag: Fix refcnt leak in error path destroying socket
inet_diag_find_one_icsk takes a reference to a socket that is not
released if sock_diag_destroy returns an error. Fix by changing
tcp_diag_destroy to manage the refcnt for all cases and remove
the sock_put calls from tcp_abort.
Fixes: c1e64e298b
("net: diag: Support destroying TCP sockets")
Reported-by: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
7b996243fa
commit
d7226c7a4d
@ -3193,7 +3193,6 @@ int tcp_abort(struct sock *sk, int err)
|
|||||||
local_bh_enable();
|
local_bh_enable();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
sock_gen_put(sk);
|
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3222,7 +3221,6 @@ int tcp_abort(struct sock *sk, int err)
|
|||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
local_bh_enable();
|
local_bh_enable();
|
||||||
release_sock(sk);
|
release_sock(sk);
|
||||||
sock_put(sk);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(tcp_abort);
|
EXPORT_SYMBOL_GPL(tcp_abort);
|
||||||
|
@ -54,11 +54,16 @@ static int tcp_diag_destroy(struct sk_buff *in_skb,
|
|||||||
{
|
{
|
||||||
struct net *net = sock_net(in_skb->sk);
|
struct net *net = sock_net(in_skb->sk);
|
||||||
struct sock *sk = inet_diag_find_one_icsk(net, &tcp_hashinfo, req);
|
struct sock *sk = inet_diag_find_one_icsk(net, &tcp_hashinfo, req);
|
||||||
|
int err;
|
||||||
|
|
||||||
if (IS_ERR(sk))
|
if (IS_ERR(sk))
|
||||||
return PTR_ERR(sk);
|
return PTR_ERR(sk);
|
||||||
|
|
||||||
return sock_diag_destroy(sk, ECONNABORTED);
|
err = sock_diag_destroy(sk, ECONNABORTED);
|
||||||
|
|
||||||
|
sock_gen_put(sk);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user