diff options
author | Phil Sutter <phil@nwl.cc> | 2017-12-09 16:52:29 +0100 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2017-12-12 13:24:01 +0100 |
commit | a2c55e04d5a1187914cba2c02810db94de499ace (patch) | |
tree | eb7af207d40217a842ee487ba2c49d0eeda7064a /src/payload.c | |
parent | 80f5d7fd66895c651c9d1e35b2353f3020ffb538 (diff) |
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 <fw@strlen.de>
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'src/payload.c')
-rw-r--r-- | src/payload.c | 7 |
1 files changed, 1 insertions, 6 deletions
diff --git a/src/payload.c b/src/payload.c index aa8a95ad..60090acc 100644 --- a/src/payload.c +++ b/src/payload.c @@ -84,11 +84,6 @@ static void payload_expr_pctx_update(struct proto_ctx *ctx, const struct proto_desc *base, *desc; unsigned int proto = 0; - if (!(left->flags & EXPR_F_PROTOCOL)) - return; - - assert(expr->op == OP_EQ); - /* Export the data in the correct byte order */ assert(right->len / BITS_PER_BYTE <= sizeof(proto)); mpz_export_data(constant_data_ptr(proto, right->len), right->value, @@ -240,7 +235,7 @@ static int payload_add_dependency(struct eval_ctx *ctx, return expr_error(ctx->msgs, expr, "dependency statement is invalid"); } - left->ops->pctx_update(&ctx->pctx, dep); + relational_expr_pctx_update(&ctx->pctx, dep); *res = stmt; return 0; } |