From: Eric Dumazet Date: Fri, 1 Sep 2017 21:03:32 +0000 (-0700) Subject: inetpeer: fix RCU lookup() X-Git-Tag: v4.14-rc1~130^2~45 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4cc5b44b29a9de9b3f841efedaa3f769066c63cc;p=platform%2Fkernel%2Flinux-rpi3.git 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 --- diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 337ad41b..e7eb590 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) {