summaryrefslogtreecommitdiffstats
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
authorEric Dumazet2019-05-16 04:39:52 +0200
committerGreg Kroah-Hartman2019-05-25 18:23:18 +0200
commit6bc3240adde519771e37d99e77140c3a93ff427a (patch)
treec2f67d5d54bfdf7d28a3bb7a3a751c5d0f5b6a23 /net/ipv6/route.c
parentipv6: fix src addr routing with the exception table (diff)
downloadkernel-qcow2-linux-6bc3240adde519771e37d99e77140c3a93ff427a.tar.gz
kernel-qcow2-linux-6bc3240adde519771e37d99e77140c3a93ff427a.tar.xz
kernel-qcow2-linux-6bc3240adde519771e37d99e77140c3a93ff427a.zip
ipv6: prevent possible fib6 leaks
[ Upstream commit 61fb0d01680771f72cc9d39783fb2c122aaad51e ] At ipv6 route dismantle, fib6_drop_pcpu_from() is responsible for finding all percpu routes and set their ->from pointer to NULL, so that fib6_ref can reach its expected value (1). The problem right now is that other cpus can still catch the route being deleted, since there is no rcu grace period between the route deletion and call to fib6_drop_pcpu_from() This can leak the fib6 and associated resources, since no notifier will take care of removing the last reference(s). I decided to add another boolean (fib6_destroying) instead of reusing/renaming exception_bucket_flushed to ease stable backports, and properly document the memory barriers used to implement this fix. This patch has been co-developped with Wei Wang. Fixes: 93531c674315 ("net/ipv6: separate handling of FIB entries from dst based routes") Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: syzbot <syzkaller@googlegroups.com> Cc: Wei Wang <weiwan@google.com> Cc: David Ahern <dsahern@gmail.com> Cc: Martin Lau <kafai@fb.com> Acked-by: Wei Wang <weiwan@google.com> Acked-by: Martin KaFai Lau <kafai@fb.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, 7 insertions, 0 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index cf61dddfea09..bf0940c42810 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1268,6 +1268,13 @@ static struct rt6_info *rt6_make_pcpu_route(struct net *net,
prev = cmpxchg(p, NULL, pcpu_rt);
BUG_ON(prev);
+ if (rt->fib6_destroying) {
+ struct fib6_info *from;
+
+ from = xchg((__force struct fib6_info **)&pcpu_rt->from, NULL);
+ fib6_info_release(from);
+ }
+
return pcpu_rt;
}