netfilter: nft_rbtree: ignore inactive matching element with no descendants
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 1 Aug 2016 11:13:08 +0000 (13:13 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 8 Aug 2016 09:27:37 +0000 (11:27 +0200)
If we find a matching element that is inactive with no descendants, we
jump to the found label, then crash because of nul-dereference on the
left branch.

Fix this by checking that the element is active and not an interval end
and skipping the logic that only applies to the tree iteration.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Tested-by: Anders K. Pedersen <akp@akp.dk>
net/netfilter/nft_rbtree.c

index 6473936d05c67aa08b7c507bb2bfd8c836bdfcce..ffe9ae062d23e48fe39f9136e8e01d3737a852af 100644 (file)
@@ -70,7 +70,6 @@ static bool nft_rbtree_lookup(const struct net *net, const struct nft_set *set,
                } else if (d > 0)
                        parent = parent->rb_right;
                else {
-found:
                        if (!nft_set_elem_active(&rbe->ext, genmask)) {
                                parent = parent->rb_left;
                                continue;
@@ -84,9 +83,12 @@ found:
                }
        }
 
-       if (set->flags & NFT_SET_INTERVAL && interval != NULL) {
-               rbe = interval;
-               goto found;
+       if (set->flags & NFT_SET_INTERVAL && interval != NULL &&
+           nft_set_elem_active(&interval->ext, genmask) &&
+           !nft_rbtree_interval_end(interval)) {
+               spin_unlock_bh(&nft_rbtree_lock);
+               *ext = &interval->ext;
+               return true;
        }
 out:
        spin_unlock_bh(&nft_rbtree_lock);