]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
netfilter: nft_set_rbtree: get command skips end element with open interval
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 2 Jul 2026 12:33:09 +0000 (14:33 +0200)
committerFlorian Westphal <fw@strlen.de>
Fri, 3 Jul 2026 12:45:21 +0000 (14:45 +0200)
The get command on intervals provide partial matches such as subranges
for usability reasons. However, an open interval has no closing end
element. If the closing element matches within the range of the open
internal, ie. its closest match is the start element of the open range,
then, return 0 but offer no matching element to userspace through
netlink as a special case. Userspace provides at least a matching start
element in this case and the closing end element matching the open
interal is ignored.

Another possibility is to report the matching start element of the open
interval for this end interval. However, this results in duplicated
matching being listed in userspace because userspace does not expect a
start element as response to a end element.

Fixes: 2aa34191f06f ("netfilter: nft_set_rbtree: use binary search array in get command")
Reported-by: Melbin K Mathew <mlbnkm1@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/nf_tables_api.c
net/netfilter/nft_set_rbtree.c

index 4884f7f7aaeee032de4edea314e35e95f987d7f2..a9eaf9455c7783efa1804bf0f724f42765cce1c4 100644 (file)
@@ -6563,6 +6563,9 @@ static int nft_get_set_elem(struct nft_ctx *ctx, const struct nft_set *set,
        if (err < 0)
                return err;
 
+       if (!elem.priv)
+               return 0;
+
        err = -ENOMEM;
        skb = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
        if (skb == NULL)
index 018bbb6df4ce43aa43b146caabc7d4dbdb123228..6222e9bb57bc901970f1085f11f8af586bffd622 100644 (file)
@@ -184,10 +184,14 @@ nft_rbtree_get(const struct net *net, const struct nft_set *set,
        if (!interval || nft_set_elem_expired(interval->from))
                return ERR_PTR(-ENOENT);
 
-       if (flags & NFT_SET_ELEM_INTERVAL_END)
+       if (flags & NFT_SET_ELEM_INTERVAL_END) {
+               if (!interval->to)
+                       return NULL;
+
                rbe = container_of(interval->to, struct nft_rbtree_elem, ext);
-       else
+       } else {
                rbe = container_of(interval->from, struct nft_rbtree_elem, ext);
+       }
 
        return &rbe->priv;
 }