]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
netfilter: nft_lookup: fix catchall element handling with inverted lookups
authorTamaki Yanagawa <ty@000ty.net>
Fri, 3 Jul 2026 16:22:57 +0000 (16:22 +0000)
committerFlorian Westphal <fw@strlen.de>
Wed, 8 Jul 2026 13:33:37 +0000 (15:33 +0200)
nft_lookup_eval() decides whether a lookup matched (`found`) from the
direct set lookup and priv->invert before falling back to the
catchall element used by interval sets (e.g. nft_set_rbtree) for the
open-ended default range. Since `found` is never recomputed after
`ext` is replaced by the catchall lookup, inverted lookups
(NFT_LOOKUP_F_INV, "!= @set") can wrongly match or wrongly skip the
catchall element, producing the wrong verdict. Fold the catchall
lookup into `ext` before computing `found`, matching the order
already used by nft_objref_map_eval().

Fixes: aaa31047a6d2 ("netfilter: nftables: add catch-all set element support")
Signed-off-by: Tamaki Yanagawa <ty@000ty.net>
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/nft_lookup.c

index ba512e94b4023fba26116ef1ce6b09e1b40d51de..19887439847d11bc38342ee8887749a472c90134 100644 (file)
@@ -103,13 +103,13 @@ void nft_lookup_eval(const struct nft_expr *expr,
        bool found;
 
        ext = nft_set_do_lookup(net, set, &regs->data[priv->sreg]);
+       if (!ext)
+               ext = nft_set_catchall_lookup(net, set);
+
        found = !!ext ^ priv->invert;
        if (!found) {
-               ext = nft_set_catchall_lookup(net, set);
-               if (!ext) {
-                       regs->verdict.code = NFT_BREAK;
-                       return;
-               }
+               regs->verdict.code = NFT_BREAK;
+               return;
        }
 
        if (ext) {