]> git.ipfire.org Git - thirdparty/nftables.git/commit
src: fix protocol context update on big-endian systems
authorPhil Sutter <phil@nwl.cc>
Sat, 9 Dec 2017 15:52:29 +0000 (16:52 +0100)
committerFlorian Westphal <fw@strlen.de>
Tue, 12 Dec 2017 12:24:01 +0000 (13:24 +0100)
commita2c55e04d5a1187914cba2c02810db94de499ace
treeeb7af207d40217a842ee487ba2c49d0eeda7064a
parent80f5d7fd66895c651c9d1e35b2353f3020ffb538
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>
include/expression.h
src/ct.c
src/evaluate.c
src/expression.c
src/meta.c
src/netlink.c
src/netlink_delinearize.c
src/payload.c