summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2025-06-26 16:52:31 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2025-08-13 20:51:08 +0200
commit3d754c8614618a7723faa4ba2e06b750f2c56c00 (patch)
tree51e4e65af131bcb0f83d484a686ad1a77e4e6967
parentaa36b04c2ff693c03ce6586a7a41b0fb8e73e4e5 (diff)
evaluate: check element key vs. set definition
commit 7f4d7fef31bd282b8e37d6d401208535a1e74d17 upstream. 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>
-rw-r--r--src/evaluate.c30
-rw-r--r--tests/shell/testcases/bogons/nft-f/symbolic_constant_print_assert7
2 files changed, 30 insertions, 7 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index 0d0634d6..bba7ef79 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1785,6 +1785,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;
@@ -1825,6 +1842,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;
@@ -2033,13 +2056,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
index 00000000..e01fb3be
--- /dev/null
+++ b/tests/shell/testcases/bogons/nft-f/symbolic_constant_print_assert
@@ -0,0 +1,7 @@
+table inet t {
+ set y {
+ typeof ip daddr . @ih,32,35
+ elements = {redirect }
+ }
+}
+reset rules