Skip to content

Commit

Permalink
ipv4: dst_entry leak in ip_send_unicast_reply()
Browse files Browse the repository at this point in the history
commit 4062090 upstream.

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

Fixes: 2e77d89 ("net: avoid a pair of dst_hold()/dst_release() in ip_append_data()")
Signed-off-by: Vasily Averin <vvs@parallels.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
  • Loading branch information
Vasily Averin authored and Ben Hutchings committed Jan 1, 2015
1 parent 7240353 commit b136685
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions net/ipv4/ip_output.c
Original file line number Diff line number Diff line change
@@ -1472,6 +1472,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr,
struct ipcm_cookie ipc;
struct flowi4 fl4;
struct rtable *rt = skb_rtable(skb);
int err;

if (ip_options_echo(&replyopts.opt.opt, skb))
return;
@@ -1509,8 +1510,13 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr,
sk->sk_priority = skb->priority;
sk->sk_protocol = ip_hdr(skb)->protocol;
sk->sk_bound_dev_if = arg->bound_dev_if;
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;
}

if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) {
if (arg->csumoffset >= 0)
*((__sum16 *)skb_transport_header(skb) +
@@ -1519,7 +1525,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, __be32 daddr,
skb->ip_summed = CHECKSUM_NONE;
ip_push_pending_frames(sk, &fl4);
}

out:
bh_unlock_sock(sk);

ip_rt_put(rt);

0 comments on commit b136685

Please sign in to comment.