From: Florian Westphal Date: Mon, 31 Mar 2025 12:27:47 +0000 (+0200) Subject: json: fix error propagation when parsing binop lhs/rhs X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=212718fc9127193b98da904a5debae6e4fd7dfc2;p=thirdparty%2Fnftables.git json: fix error propagation when parsing binop lhs/rhs commit 1b6470ab1c4eff46986e65db1b69278f13c26666 upstream. Malformed input returns NULL when decoding left/right side of binop. This causes a NULL dereference in expr_evaluate_binop; left/right must point to a valid expression. Fix this in the parser, else would have to sprinkle NULL checks all over the evaluation code. After fix, loading the bogon yields: internal:0:0-0: Error: Malformed object (too many properties): '{}'. internal:0:0-0: Error: could not decode binop rhs, '<<'. internal:0:0-0: Error: Invalid mangle statement value internal:0:0-0: Error: Parsing expr array at index 1 failed. internal:0:0-0: Error: Parsing command array at index 3 failed. Fixes: 0ac39384fd9e ("json: Accept more than two operands in binary expressions") Signed-off-by: Florian Westphal Reviewed-by: Pablo Neira Ayuso --- diff --git a/src/parser_json.c b/src/parser_json.c index e8fed0d2..c7649ccf 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -1138,11 +1138,25 @@ static struct expr *json_parse_binop_expr(struct json_ctx *ctx, if (json_array_size(root) > 2) { left = json_parse_primary_expr(ctx, json_array_get(root, 0)); + if (!left) { + json_error(ctx, "Failed to parse LHS of binop expression."); + return NULL; + } right = json_parse_primary_expr(ctx, json_array_get(root, 1)); + if (!right) { + json_error(ctx, "Failed to parse RHS of binop expression."); + expr_free(left); + return NULL; + } left = binop_expr_alloc(int_loc, thisop, left, right); for (i = 2; i < json_array_size(root); i++) { jright = json_array_get(root, i); right = json_parse_primary_expr(ctx, jright); + if (!right) { + json_error(ctx, "Failed to parse RHS of binop expression."); + expr_free(left); + return NULL; + } left = binop_expr_alloc(int_loc, thisop, left, right); } return left;