From 4cc5b44b29a9de9b3f841efedaa3f769066c63cc Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 1 Sep 2017 14:03:32 -0700 Subject: inetpeer: fix RCU lookup() Excess of seafood or something happened while I cooked the commit adding RB tree to inetpeer. Of course, RCU rules need to be respected or bad things can happen. In this particular loop, we need to read *pp once per iteration, not twice. Fixes: b145425f269a ("inetpeer: remove AVL implementation in favor of RB tree") Reported-by: John Sperbeck Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/inetpeer.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'net/ipv4/inetpeer.c') diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 337ad41bb80a..e7eb590c86ce 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c @@ -102,15 +102,18 @@ static struct inet_peer *lookup(const struct inetpeer_addr *daddr, struct rb_node **parent_p, struct rb_node ***pp_p) { - struct rb_node **pp, *parent; + struct rb_node **pp, *parent, *next; struct inet_peer *p; pp = &base->rb_root.rb_node; parent = NULL; - while (*pp) { + while (1) { int cmp; - parent = rcu_dereference_raw(*pp); + next = rcu_dereference_raw(*pp); + if (!next) + break; + parent = next; p = rb_entry(parent, struct inet_peer, rb_node); cmp = inetpeer_addr_cmp(daddr, &p->daddr); if (cmp == 0) { -- cgit v1.2.3-59-g8ed1b