From 4121175cc243a15bdb8c226a335f67cedd98680e Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Thu, 11 Jan 2024 18:14:16 +0100 Subject: evaluate: add missing range checks for dup,fwd and payload statements Else we assert with: BUG: unknown expression type range nft: src/netlink_linearize.c:912: netlink_gen_expr: Assertion `0' failed. While at it, condense meta and exthdr to reuse the same helper. Signed-off-by: Florian Westphal --- src/evaluate.c | 88 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 38 deletions(-) (limited to 'src/evaluate.c') diff --git a/src/evaluate.c b/src/evaluate.c index d11bed01..b13e7c02 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -74,6 +74,33 @@ static int __fmtstring(3, 4) set_error(struct eval_ctx *ctx, return -1; } +static const char *stmt_name(const struct stmt *stmt) +{ + switch (stmt->ops->type) { + case STMT_NAT: + switch (stmt->nat.type) { + case NFT_NAT_SNAT: + return "snat"; + case NFT_NAT_DNAT: + return "dnat"; + case NFT_NAT_REDIR: + return "redirect"; + case NFT_NAT_MASQ: + return "masquerade"; + } + break; + default: + break; + } + + return stmt->ops->name; +} + +static int stmt_error_range(struct eval_ctx *ctx, const struct stmt *stmt, const struct expr *e) +{ + return expr_error(ctx->msgs, e, "%s: range argument not supported", stmt_name(stmt)); +} + static void key_fix_dtype_byteorder(struct expr *key) { const struct datatype *dtype = key->dtype; @@ -3085,13 +3112,8 @@ static int stmt_evaluate_exthdr(struct eval_ctx *ctx, struct stmt *stmt) if (ret < 0) return ret; - switch (stmt->exthdr.val->etype) { - case EXPR_RANGE: - return expr_error(ctx->msgs, stmt->exthdr.val, - "cannot be a range"); - default: - break; - } + if (stmt->exthdr.val->etype == EXPR_RANGE) + return stmt_error_range(ctx, stmt, stmt->exthdr.val); return 0; } @@ -3124,6 +3146,9 @@ static int stmt_evaluate_payload(struct eval_ctx *ctx, struct stmt *stmt) payload->byteorder) < 0) return -1; + if (stmt->payload.val->etype == EXPR_RANGE) + return stmt_error_range(ctx, stmt, stmt->payload.val); + need_csum = stmt_evaluate_payload_need_csum(payload); if (!payload_needs_adjustment(payload)) { @@ -3283,15 +3308,8 @@ static int stmt_evaluate_meta(struct eval_ctx *ctx, struct stmt *stmt) if (ret < 0) return ret; - switch (stmt->meta.expr->etype) { - case EXPR_RANGE: - ret = expr_error(ctx->msgs, stmt->meta.expr, - "Meta expression cannot be a range"); - break; - default: - break; - - } + if (stmt->meta.expr->etype == EXPR_RANGE) + return stmt_error_range(ctx, stmt, stmt->meta.expr); return ret; } @@ -3314,6 +3332,9 @@ static int stmt_evaluate_ct(struct eval_ctx *ctx, struct stmt *stmt) return stmt_error(ctx, stmt, "ct secmark must not be set to constant value"); + if (stmt->ct.expr->etype == EXPR_RANGE) + return stmt_error_range(ctx, stmt, stmt->ct.expr); + return 0; } @@ -3831,28 +3852,6 @@ static int nat_evaluate_transport(struct eval_ctx *ctx, struct stmt *stmt, return 0; } -static const char *stmt_name(const struct stmt *stmt) -{ - switch (stmt->ops->type) { - case STMT_NAT: - switch (stmt->nat.type) { - case NFT_NAT_SNAT: - return "snat"; - case NFT_NAT_DNAT: - return "dnat"; - case NFT_NAT_REDIR: - return "redirect"; - case NFT_NAT_MASQ: - return "masquerade"; - } - break; - default: - break; - } - - return stmt->ops->name; -} - static int stmt_evaluate_l3proto(struct eval_ctx *ctx, struct stmt *stmt, uint8_t family) { @@ -4250,6 +4249,9 @@ static int stmt_evaluate_dup(struct eval_ctx *ctx, struct stmt *stmt) &stmt->dup.dev); if (err < 0) return err; + + if (stmt->dup.dev->etype == EXPR_RANGE) + return stmt_error_range(ctx, stmt, stmt->dup.dev); } break; case NFPROTO_NETDEV: @@ -4268,6 +4270,10 @@ static int stmt_evaluate_dup(struct eval_ctx *ctx, struct stmt *stmt) default: return stmt_error(ctx, stmt, "unsupported family"); } + + if (stmt->dup.to->etype == EXPR_RANGE) + return stmt_error_range(ctx, stmt, stmt->dup.to); + return 0; } @@ -4289,6 +4295,9 @@ static int stmt_evaluate_fwd(struct eval_ctx *ctx, struct stmt *stmt) if (err < 0) return err; + if (stmt->fwd.dev->etype == EXPR_RANGE) + return stmt_error_range(ctx, stmt, stmt->fwd.dev); + if (stmt->fwd.addr != NULL) { switch (stmt->fwd.family) { case NFPROTO_IPV4: @@ -4307,6 +4316,9 @@ static int stmt_evaluate_fwd(struct eval_ctx *ctx, struct stmt *stmt) &stmt->fwd.addr); if (err < 0) return err; + + if (stmt->fwd.addr->etype == EXPR_RANGE) + return stmt_error_range(ctx, stmt, stmt->fwd.addr); } break; default: -- cgit v1.2.3