From dd86c42d0c48cf8f3aa0be5ebbf5cde45474562e Mon Sep 17 00:00:00 2001 From: "liping.zhang" Date: Wed, 17 Feb 2016 13:32:20 +0800 Subject: [PATCH] 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 8718af894332..50a58e1b05a6 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3501,16 +3501,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