lkml.org 
[lkml]   [2014]   [Nov]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.12 014/206] ipv4: dst_entry leak in ip_send_unicast_reply()
    Date
    From: Vasily Averin <vvs@parallels.com>

    3.12-stable review patch. If anyone has any objections, please let me know.

    ===============

    [ Upstream commit 4062090e3e5caaf55bed4523a69f26c3265cc1d2 ]

    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: 2e77d89b2fa8 ("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>
    ---
    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 c1cb9475fadf..c2dcee28d071 100644
    --- a/net/ipv4/ip_output.c
    +++ b/net/ipv4/ip_output.c
    @@ -1478,6 +1478,7 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
    struct sk_buff *nskb;
    struct sock *sk;
    struct inet_sock *inet;
    + int err;

    if (ip_options_echo(&replyopts.opt.opt, skb))
    return;
    @@ -1514,8 +1515,13 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
    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)
    @@ -1527,7 +1533,7 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr,
    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);
    --
    2.1.3


    \
     
     \ /
      Last update: 2014-11-18 17:01    [W:4.460 / U:0.080 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site