From mboxrd@z Thu Jan 1 00:00:00 1970 From: Pablo Neira Ayuso Subject: [PATCH nf] netfilter: nft_rbtree: ignore inactive matching element with no descendants Date: Mon, 1 Aug 2016 13:38:43 +0200 Message-ID: <1470051523-12223-1-git-send-email-pablo@netfilter.org> Cc: fw@strlen.de, akp@akp.dk To: netfilter-devel@vger.kernel.org Return-path: Received: from mail.us.es ([193.147.175.20]:42673 "EHLO mail.us.es" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753283AbcHALlB (ORCPT ); Mon, 1 Aug 2016 07:41:01 -0400 Received: from antivirus1-rhel7.int (unknown [192.168.2.11]) by mail.us.es (Postfix) with ESMTP id 6A803168395 for ; Mon, 1 Aug 2016 13:39:27 +0200 (CEST) Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id 5C2CBFF6FF for ; Mon, 1 Aug 2016 13:39:27 +0200 (CEST) Received: from antivirus1-rhel7.int (localhost [127.0.0.1]) by antivirus1-rhel7.int (Postfix) with ESMTP id EFA577E077 for ; Mon, 1 Aug 2016 13:39:24 +0200 (CEST) Sender: netfilter-devel-owner@vger.kernel.org List-ID: 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 --- Slightly larger than Florian's fix but we get rid of the goto here that gcc consider branches with gotos as unlikely. net/netfilter/nft_rbtree.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/netfilter/nft_rbtree.c b/net/netfilter/nft_rbtree.c index 6473936..ffe9ae0 100644 --- a/net/netfilter/nft_rbtree.c +++ b/net/netfilter/nft_rbtree.c @@ -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); -- 2.1.4