summaryrefslogtreecommitdiffstats
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
authorXin Long2018-11-13 17:48:28 +0100
committerGreg Kroah-Hartman2018-11-23 08:17:02 +0100
commitb536dd802a36dd14e8d5e68201cecab46ccb9669 (patch)
treea97e3bfeb73e32315f2e44b7e90987611d4446f8 /net/ipv6/route.c
parentip_tunnel: don't force DF when MTU is locked (diff)
downloadkernel-qcow2-linux-b536dd802a36dd14e8d5e68201cecab46ccb9669.tar.gz
kernel-qcow2-linux-b536dd802a36dd14e8d5e68201cecab46ccb9669.tar.xz
kernel-qcow2-linux-b536dd802a36dd14e8d5e68201cecab46ccb9669.zip
ipv6: fix a dst leak when removing its exception
[ Upstream commit 761f60261b4401aa368d71d431b4c218af0efcee ] These is no need to hold dst before calling rt6_remove_exception_rt(). The call to dst_hold_safe() in ip6_link_failure() was for ip6_del_rt(), which has been removed in Commit 93531c674315 ("net/ipv6: separate handling of FIB entries from dst based routes"). Otherwise, it will cause a dst leak. This patch is to simply remove the dst_hold_safe() call before calling rt6_remove_exception_rt() and also do the same in ip6_del_cached_rt(). It's safe, because the removal of the exception that holds its dst's refcnt is protected by rt6_exception_lock. Fixes: 93531c674315 ("net/ipv6: separate handling of FIB entries from dst based routes") Fixes: 23fb93a4d3f1 ("net/ipv6: Cleanup exception and cache route handling") Reported-by: Li Shuang <shuali@redhat.com> Signed-off-by: Xin Long <lucien.xin@gmail.com> Reviewed-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r--net/ipv6/route.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 1cf00d857fc1..ed72ae3c54e7 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2263,8 +2263,7 @@ static void ip6_link_failure(struct sk_buff *skb)
if (rt) {
rcu_read_lock();
if (rt->rt6i_flags & RTF_CACHE) {
- if (dst_hold_safe(&rt->dst))
- rt6_remove_exception_rt(rt);
+ rt6_remove_exception_rt(rt);
} else {
struct fib6_info *from;
struct fib6_node *fn;
@@ -3266,8 +3265,8 @@ static int ip6_del_cached_rt(struct rt6_info *rt, struct fib6_config *cfg)
if (cfg->fc_flags & RTF_GATEWAY &&
!ipv6_addr_equal(&cfg->fc_gateway, &rt->rt6i_gateway))
goto out;
- if (dst_hold_safe(&rt->dst))
- rc = rt6_remove_exception_rt(rt);
+
+ rc = rt6_remove_exception_rt(rt);
out:
return rc;
}