From ff31efd5ae7deca3353989432b040b28517fb657 Mon Sep 17 00:00:00 2001 From: "liping.zhang" Date: Fri, 19 Feb 2016 09:07:03 +0800 Subject: net: tcp: fix rtable leak in tcp_is_local[6] ip_rt_put/ip6_rt_put call is missed after route lookup routine. So if lookup returns ok, rtable leak will happen. Change-Id: Ica137043879b4305b70401cf7e8efda24405e3ff Signed-off-by: Liping Zhang --- net/ipv4/tcp.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 0d486f654..1bb6eaad1 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3528,16 +3528,24 @@ void __init tcp_init(void) static int tcp_is_local(struct net *net, __be32 addr) { struct rtable *rt; struct flowi4 fl4 = { .daddr = addr }; + int is_local; rt = ip_route_output_key(net, &fl4); if (IS_ERR_OR_NULL(rt)) return 0; - return rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK); + + is_local = rt->dst.dev && (rt->dst.dev->flags & IFF_LOOPBACK); + ip_rt_put(rt); + return is_local; } #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) static int tcp_is_local6(struct net *net, struct in6_addr *addr) { struct rt6_info *rt6 = rt6_lookup(net, addr, addr, 0, 0); - return rt6 && rt6->dst.dev && (rt6->dst.dev->flags & IFF_LOOPBACK); + int is_local; + + is_local = rt6 && rt6->dst.dev && (rt6->dst.dev->flags & IFF_LOOPBACK); + ip6_rt_put(rt6); + return is_local; } #endif -- cgit v1.2.3