ipv6: grab rt->rt6i_ref before allocating pcpu rt
authorWei Wang <weiwan@google.com>
Fri, 6 Oct 2017 19:06:04 +0000 (12:06 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Dec 2017 13:26:27 +0000 (14:26 +0100)
commit9704f8147e88213f2fa580f713b42b08a4f1a7d2
treef17385829da1c9ddd0bcf44138f45fad5c09d22e
parent2f48fc1742a2da6196482695ec3bcd2438d24a13
ipv6: grab rt->rt6i_ref before allocating pcpu rt

[ Upstream commit a94b9367e044ba672c9f4105eb1516ff6ff4948a ]

After rwlock is replaced with rcu and spinlock, ip6_pol_route() will be
called with only rcu held. That means rt6 route deletion could happen
simultaneously with rt6_make_pcpu_rt(). This could potentially cause
memory leak if rt6_release() is called right before rt6_make_pcpu_rt()
on the same route.

This patch grabs rt->rt6i_ref safely before calling rt6_make_pcpu_rt()
to make sure rt6_release() will not get triggered while
rt6_make_pcpu_rt() is in progress. And rt6_release() is called after
rt6_make_pcpu_rt() is finished.

Note: As we are incrementing rt->rt6i_ref in ip6_pol_route(), there is a
very slim chance that fib6_purge_rt() will be triggered unnecessarily
when deleting a route if ip6_pol_route() running on another thread picks
this route as well and tries to make pcpu cache for it.

Signed-off-by: Wei Wang <weiwan@google.com>
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/ipv6/route.c