Discussion:
[PATCH] ipv4: dst_entry leak in ip_send_unicast_reply()
Vasily Averin
2014-10-15 12:24:02 UTC
Permalink
Fixes: 2e77d89b2fa8 ("net: avoid a pair of dst_hold()/dst_release() in ip_append_data()")

ip_setup_cork() called inside ip_append_data() steals dst entry from rt to cork
and in case errors in __ip_append_data() nobody frees stolen dst entry

Signed-off-by: Vasily Averin <***@parallels.com>
---
net/ipv4/ip_output.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index e35b712..88e5ef2 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1535,6 +1535,7 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb,
struct sk_buff *nskb;
struct sock *sk;
struct inet_sock *inet;
+ int err;

if (__ip_options_echo(&replyopts.opt.opt, skb, sopt))
return;
@@ -1574,8 +1575,13 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb,
sock_net_set(sk, net);
__skb_queue_head_init(&sk->sk_write_queue);
sk->sk_sndbuf = sysctl_wmem_default;
- ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base, len, 0,
- &ipc, &rt, MSG_DONTWAIT);
+ err = ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base,
+ len, 0, &ipc, &rt, MSG_DONTWAIT);
+ if (unlikely(err)) {
+ ip_flush_pending_frames(sk);
+ goto out;
+ }
+
nskb = skb_peek(&sk->sk_write_queue);
if (nskb) {
if (arg->csumoffset >= 0)
@@ -1587,7 +1593,7 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb,
skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb));
ip_push_pending_frames(sk, &fl4);
}
-
+out:
put_cpu_var(unicast_sock);

ip_rt_put(rt);
--
1.9.1
David Miller
2014-10-17 15:59:32 UTC
Permalink
From: Vasily Averin <***@parallels.com>
Date: Wed, 15 Oct 2014 16:24:02 +0400
Post by Vasily Averin
Fixes: 2e77d89b2fa8 ("net: avoid a pair of dst_hold()/dst_release() in ip_append_data()")
ip_setup_cork() called inside ip_append_data() steals dst entry from rt to cork
and in case errors in __ip_append_data() nobody frees stolen dst entry
Please, in the future, put the Fixes: tag first in the list of signoffs.

Eric, please review this change, it looks good to me.
Eric Dumazet
2014-10-17 16:56:29 UTC
Permalink
Post by David Miller
Date: Wed, 15 Oct 2014 16:24:02 +0400
Post by Vasily Averin
Fixes: 2e77d89b2fa8 ("net: avoid a pair of dst_hold()/dst_release() in ip_append_data()")
ip_setup_cork() called inside ip_append_data() steals dst entry from rt to cork
and in case errors in __ip_append_data() nobody frees stolen dst entry
Please, in the future, put the Fixes: tag first in the list of signoffs.
Eric, please review this change, it looks good to me.
It is good indeed, thanks !

Acked-by: Eric Dumazet <***@google.com>
David Miller
2014-10-17 19:30:52 UTC
Permalink
From: Vasily Averin <***@parallels.com>
Date: Wed, 15 Oct 2014 16:24:02 +0400
Post by Vasily Averin
Fixes: 2e77d89b2fa8 ("net: avoid a pair of dst_hold()/dst_release() in ip_append_data()")
ip_setup_cork() called inside ip_append_data() steals dst entry from rt to cork
and in case errors in __ip_append_data() nobody frees stolen dst entry
Applied and queued up for -stable, thanks everyone!

Loading...