]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
evaluate: check element key vs. set definition
authorFlorian Westphal <fw@strlen.de>
Thu, 26 Jun 2025 14:52:31 +0000 (16:52 +0200)
committerFlorian Westphal <fw@strlen.de>
Sun, 13 Jul 2025 12:53:00 +0000 (14:53 +0200)
Included bogon asserts with:
 src/datatype.c:253: symbolic_constant_print: Assertion `expr->len / BITS_PER_BYTE <= sizeof(val)' failed.

Resolve this by validating that the set element key matches the set key
definition.

After this, loading the bogon file gives:
Error: Element mismatches set definition, expected concatenation of (IPv4 address, integer), not 'ICMP type'
elements = {redirect }
           ^^^^^^^^

Signed-off-by: Florian Westphal <fw@strlen.de>
src/evaluate.c
tests/shell/testcases/bogons/nft-f/symbolic_constant_print_assert [new file with mode: 0644]

index 1fa4cb784a8881f80fd4b0d58dec814217a63c0f..9c9059086058587273ad16953a56dd42bb804061 100644 (file)
@@ -1917,6 +1917,23 @@ static int __expr_evaluate_set_elem(struct eval_ctx *ctx, struct expr *elem)
        return 0;
 }
 
+static bool datatype_compatible(const struct datatype *a, const struct datatype *b)
+{
+       return (a->type == TYPE_MARK &&
+               datatype_equal(datatype_basetype(a), datatype_basetype(b))) ||
+               datatype_equal(a, b);
+}
+
+static bool elem_key_compatible(const struct expr *set_key,
+                               const struct expr *elem_key)
+{
+       /* Catchall element is always compatible with the set key declaration */
+       if (elem_key->etype == EXPR_SET_ELEM_CATCHALL)
+               return true;
+
+       return datatype_compatible(set_key->dtype, elem_key->dtype);
+}
+
 static int expr_evaluate_set_elem(struct eval_ctx *ctx, struct expr **expr)
 {
        struct expr *elem = *expr;
@@ -1959,6 +1976,12 @@ static int expr_evaluate_set_elem(struct eval_ctx *ctx, struct expr **expr)
                }
        }
 
+       if (ctx->set && !elem_key_compatible(ctx->ectx.key, elem->key))
+               return expr_error(ctx->msgs, elem,
+                                 "Element mismatches %s definition, expected %s, not '%s'",
+                                 set_is_map(ctx->set->flags) ? "map" : "set",
+                                 ctx->ectx.key->dtype->desc, elem->key->dtype->desc);
+
        datatype_set(elem, elem->key->dtype);
        elem->len   = elem->key->len;
        elem->flags = elem->key->flags;
@@ -2171,13 +2194,6 @@ static int mapping_expr_expand(struct eval_ctx *ctx)
        return 0;
 }
 
-static bool datatype_compatible(const struct datatype *a, const struct datatype *b)
-{
-       return (a->type == TYPE_MARK &&
-               datatype_equal(datatype_basetype(a), datatype_basetype(b))) ||
-               datatype_equal(a, b);
-}
-
 static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr)
 {
        struct expr *map = *expr, *mappings;
diff --git a/tests/shell/testcases/bogons/nft-f/symbolic_constant_print_assert b/tests/shell/testcases/bogons/nft-f/symbolic_constant_print_assert
new file mode 100644 (file)
index 0000000..e01fb3b
--- /dev/null
@@ -0,0 +1,7 @@
+table inet t {
+        set y {
+                typeof ip daddr . @ih,32,35
+                elements = {redirect }
+        }
+}
+reset   rules