summaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
authorWei Wang <weiwan@google.com>2017-10-06 12:06:06 -0700
committerDavid S. Miller <davem@davemloft.net>2017-10-07 21:22:58 +0100
commitd3843fe5fd45be0e04a251a2cc68893c859a31bd (patch)
tree57ebae60cb5df226a1fe21c8655f767eedc41fb7 /net/ipv6/addrconf.c
parent51e398e86d61b69b9a4be49ff7f6afeb87530df1 (diff)
downloadtalos-op-linux-d3843fe5fd45be0e04a251a2cc68893c859a31bd.tar.gz
talos-op-linux-d3843fe5fd45be0e04a251a2cc68893c859a31bd.zip
ipv6: replace dst_hold() with dst_hold_safe() in routing code
With rwlock, it is safe to call dst_hold() in the read thread because read thread is guaranteed to be separated from write thread. However, after we replace rwlock with rcu, it is no longer safe to use dst_hold(). A dst might already have been deleted but is waiting for the rcu grace period to pass before freeing the memory when a read thread is trying to do dst_hold(). This could potentially cause double free issue. So this commit replaces all dst_hold() with dst_hold_safe() in all read thread to avoid this double free issue. And in order to make the code more compact, a new function ip6_hold_safe() is introduced. It calls dst_hold_safe() first, and if that fails, it will either fall back to hold and return net->ipv6.ip6_null_entry or set rt to NULL according to the caller's need. 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>
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 873afafddfc4..f86e931d555e 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2333,7 +2333,8 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
continue;
if ((rt->rt6i_flags & noflags) != 0)
continue;
- dst_hold(&rt->dst);
+ if (!dst_hold_safe(&rt->dst))
+ rt = NULL;
break;
}
out:
OpenPOWER on IntegriCloud