From a2c55e04d5a1187914cba2c02810db94de499ace Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sat, 9 Dec 2017 16:52:29 +0100 Subject: src: fix protocol context update on big-endian systems There is an obscure bug on big-endian systems when trying to list a rule containing the expression 'ct helper tftp' which triggers the assert() call in mpz_get_type(). Florian identified the cause: ct_expr_pctx_update() is called for the relational expression which calls mpz_get_uint32() to get RHS value (assuming it is a protocol number). On big-endian systems, the misinterpreted value exceeds UINT_MAX. Expressions' pctx_update() callback should only be called for protocol matches, so ct_meta_common_postprocess() lacked a check for 'left->flags & EXPR_F_PROTOCOL' like the one already present in payload_expr_pctx_update(). In order to fix this in a clean way, this patch introduces a wrapper relational_expr_pctx_update() to be used instead of directly calling LHS's pctx_update() callback which unifies the necessary checks (and adds one more assert): - assert(expr->ops->type == EXPR_RELATIONAL) -> This is new, just to ensure the wrapper is called properly. - assert(expr->op == OP_EQ) -> This was moved from {ct,meta,payload}_expr_pctx_update(). - left->ops->pctx_update != NULL -> This was taken from expr_evaluate_relational(), a necessary requirement for the introduced wrapper to function at all. - (left->flags & EXPR_F_PROTOCOL) != 0 -> The crucial missing check which led to the problem. Suggested-by: Florian Westphal Signed-off-by: Phil Sutter Signed-off-by: Florian Westphal --- src/evaluate.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/evaluate.c') diff --git a/src/evaluate.c b/src/evaluate.c index 758e7bbe..7fe738d8 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -746,7 +746,7 @@ static int ct_gen_nh_dependency(struct eval_ctx *ctx, struct expr *ct) constant_data_ptr(ct->ct.nfproto, left->len)); dep = relational_expr_alloc(&ct->location, OP_EQ, left, right); - left->ops->pctx_update(&ctx->pctx, dep); + relational_expr_pctx_update(&ctx->pctx, dep); nstmt = expr_stmt_alloc(&dep->location, dep); @@ -1635,9 +1635,7 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr) * Update protocol context for payload and meta iiftype * equality expressions. */ - if (left->flags & EXPR_F_PROTOCOL && - left->ops->pctx_update) - left->ops->pctx_update(&ctx->pctx, rel); + relational_expr_pctx_update(&ctx->pctx, rel); if (left->ops->type == EXPR_CONCAT) return 0; -- cgit v1.2.3