diff options
author | Florian Westphal <fw@strlen.de> | 2025-04-02 07:18:18 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2025-07-29 02:38:28 +0200 |
commit | 52bdb14bdc2dd9855abe124c87ed279728b9ddf2 (patch) | |
tree | 5eedf1b39897259a427c6a4c5e69e0268c1c1169 | |
parent | 56b231805a97c556c8adc7010e15ef0581dd35e3 (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.c | 20 |
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; |