]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
segtree: fix get element command with open intervals
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 2 Jul 2026 09:57:00 +0000 (11:57 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 3 Jul 2026 08:15:21 +0000 (10:15 +0200)
Skip the closing end element in case this is an open interval.
Otherwise, a bogus end element max(type) + 1 is provided, eg. in
inet_service, this results as a 0x10000 with end interval flag
which is interpreted by the kernel as a matching closing element.

Fixes: a43cc8d53096 ("src: support for get element command")
Reported-by: Melbin K Mathew <mlbnkm1@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/segtree.c

index a12820bcf1ecede08b6be648064c3f8dbd69bb7a..a721078cfa599dd8be18b9b9bc039979336a2a02 100644 (file)
@@ -73,12 +73,13 @@ static void set_elem_expr_add(const struct set *set, struct expr *init,
 struct expr *get_set_intervals(const struct set *set, const struct expr *init)
 {
        enum byteorder byteorder = get_key_byteorder(set->key);
+       mpz_t low, high, mask;
        struct expr *new_init;
-       mpz_t low, high;
        struct expr *i;
 
        mpz_init2(low, set->key->len);
        mpz_init2(high, set->key->len);
+       mpz_init2(mask, set->key->len);
 
        new_init = set_expr_alloc(&internal_location, NULL);
 
@@ -105,6 +106,11 @@ struct expr *get_set_intervals(const struct set *set, const struct expr *init)
                        range_expr_value_low(low, i->key);
                        set_elem_expr_add(set, new_init, low, 0, byteorder);
                        range_expr_value_high(high, i->key);
+                       mpz_bitmask(mask, i->len);
+                       if (set_is_non_concat_range(set) &&
+                           !mpz_cmp(mask, high))
+                               break;
+
                        mpz_add_ui(high, high, 1);
                        set_elem_expr_add(set, new_init, high,
                                          EXPR_F_INTERVAL_END, byteorder);
@@ -115,6 +121,7 @@ struct expr *get_set_intervals(const struct set *set, const struct expr *init)
                }
        }
 
+       mpz_clear(mask);
        mpz_clear(low);
        mpz_clear(high);