summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2025-04-02 07:18:18 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2025-07-29 02:38:28 +0200
commit52bdb14bdc2dd9855abe124c87ed279728b9ddf2 (patch)
tree5eedf1b39897259a427c6a4c5e69e0268c1c1169
parent56b231805a97c556c8adc7010e15ef0581dd35e3 (diff)
parser_json: only allow concatenations with 2 or more expressions
commit 713592c6008a8c589a00d3d3d2e49709ff2de62c upstream. The bison parser enforces this implicitly by grammar rules. Because subkeys have to be conatenated via ".", notation, e.g. "mark . ip saddr", all concatenation expressions always consist of at least two elements. But this doesn't apply to the json frontend which just uses an array: it can be empty or only contain one element. The included reproducer makes the eval stage set the "concatenation" flag on the interval set. This prevents the needed conversion code to turn the element values into ranges from getting run. The reproducer asserts with: nft: src/intervals.c:786: setelem_to_interval: Assertion `key->etype == EXPR_RANGE_VALUE' failed. Convert the assertion to BUG() so we can see what element type got passed to the set interval code in case we have further issues in this area. Reject 0-or-1-element concatenations from the json parser. Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--src/parser_json.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/src/parser_json.c b/src/parser_json.c
index 51ce2135..eb6537d4 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -1179,6 +1179,16 @@ static struct expr *json_parse_binop_expr(struct json_ctx *ctx,
return binop_expr_alloc(int_loc, thisop, left, right);
}
+static struct expr *json_check_concat_expr(struct json_ctx *ctx, struct expr *e)
+{
+ if (e->size >= 2)
+ return e;
+
+ json_error(ctx, "Concatenation with %d elements is illegal", e->size);
+ expr_free(e);
+ return NULL;
+}
+
static struct expr *json_parse_concat_expr(struct json_ctx *ctx,
const char *type, json_t *root)
{
@@ -1212,7 +1222,7 @@ static struct expr *json_parse_concat_expr(struct json_ctx *ctx,
}
compound_expr_add(expr, tmp);
}
- return expr;
+ return expr ? json_check_concat_expr(ctx, expr) : NULL;
}
static struct expr *json_parse_prefix_expr(struct json_ctx *ctx,
@@ -1671,13 +1681,7 @@ static struct expr *json_parse_dtype_expr(struct json_ctx *ctx, json_t *root)
compound_expr_add(expr, i);
}
- if (list_empty(&expr->expressions)) {
- json_error(ctx, "Empty concatenation");
- expr_free(expr);
- return NULL;
- }
-
- return expr;
+ return json_check_concat_expr(ctx, expr);
} else if (json_is_object(root)) {
const char *key;
json_t *val;