summaryrefslogtreecommitdiffstats
path: root/src/evaluate.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2024-01-11 18:14:16 +0100
committerFlorian Westphal <fw@strlen.de>2024-01-11 21:34:08 +0100
commit4121175cc243a15bdb8c226a335f67cedd98680e (patch)
treec927d7425e7f3d9158e80477b31fb5b13d5ac597 /src/evaluate.c
parent1d03ab5267bdbc7c0bcb041efaad42a462fdeb5f (diff)
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 <fw@strlen.de>
Diffstat (limited to 'src/evaluate.c')
-rw-r--r--src/evaluate.c88
1 files changed, 50 insertions, 38 deletions
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: