summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2016-08-29 13:20:08 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2016-08-29 20:30:29 +0200
commit06c8f6fccc689cae71cc84d4d6d27098c9e15089 (patch)
tree1a6ac94ee167c56b15522fdfd5dab94a86ba509f /src
parentcb7cb885d65ec02aa33872b4bd382ef8a692113a (diff)
evaluate: validate maximum hash and numgen value
We can validate that values don't get over the maximum datatype length, this is expressed in number of bits, so the maximum value is always power of 2. However, since we got the hash and numgen expressions, the user should not set a value higher that what the specified modulus option, which may not be power of 2. This patch extends the expression context with a new optional field to store the maximum value. After this patch, nft bails out if the user specifies non-sense rules like those below: # nft add rule x y jhash ip saddr mod 10 seed 0xa 10 <cmdline>:1:45-46: Error: Value 10 exceeds valid range 0-9 add rule x y jhash ip saddr mod 10 seed 0xa 10 ^^ The modulus sets a valid value range of [0, n), so n is out of the valid value range. # nft add rule x y numgen inc mod 10 eq 12 <cmdline>:1:35-36: Error: Value 12 exceeds valid range 0-9 add rule x y numgen inc mod 10 eq 12 ^^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/evaluate.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index 39573e96..7eb28f2c 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -266,12 +266,23 @@ static int expr_evaluate_string(struct eval_ctx *ctx, struct expr **exprp)
static int expr_evaluate_integer(struct eval_ctx *ctx, struct expr **exprp)
{
struct expr *expr = *exprp;
+ char *valstr, *rangestr;
mpz_t mask;
+ if (ctx->ectx.maxval > 0 &&
+ mpz_cmp_ui(expr->value, ctx->ectx.maxval) > 0) {
+ valstr = mpz_get_str(NULL, 10, expr->value);
+ expr_error(ctx->msgs, expr,
+ "Value %s exceeds valid range 0-%u",
+ valstr, ctx->ectx.maxval);
+ free(valstr);
+ return -1;
+ }
+
mpz_init_bitmask(mask, ctx->ectx.len);
if (mpz_cmp(expr->value, mask) > 0) {
- char *valstr = mpz_get_str(NULL, 10, expr->value);
- char *rangestr = mpz_get_str(NULL, 10, mask);
+ valstr = mpz_get_str(NULL, 10, expr->value);
+ rangestr = mpz_get_str(NULL, 10, mask);
expr_error(ctx->msgs, expr,
"Value %s exceeds valid range 0-%s",
valstr, rangestr);
@@ -309,7 +320,7 @@ static int expr_evaluate_value(struct eval_ctx *ctx, struct expr **expr)
static int expr_evaluate_primary(struct eval_ctx *ctx, struct expr **expr)
{
__expr_set_context(&ctx->ectx, (*expr)->dtype, (*expr)->byteorder,
- (*expr)->len);
+ (*expr)->len, 0);
return 0;
}
@@ -1186,9 +1197,13 @@ static void expr_dtype_integer_compatible(struct eval_ctx *ctx,
static int expr_evaluate_numgen(struct eval_ctx *ctx, struct expr **exprp)
{
- expr_dtype_integer_compatible(ctx, *exprp);
+ struct expr *expr = *exprp;
+
+ expr_dtype_integer_compatible(ctx, expr);
- return expr_evaluate_primary(ctx, exprp);
+ __expr_set_context(&ctx->ectx, expr->dtype, expr->byteorder, expr->len,
+ expr->numgen.mod - 1);
+ return 0;
}
static int expr_evaluate_hash(struct eval_ctx *ctx, struct expr **exprp)
@@ -1205,7 +1220,8 @@ static int expr_evaluate_hash(struct eval_ctx *ctx, struct expr **exprp)
* expression to be hashed. Since this input is transformed to a 4 bytes
* integer, restore context to the datatype that results from hashing.
*/
- expr_set_context(&ctx->ectx, expr->dtype, expr->len);
+ __expr_set_context(&ctx->ectx, expr->dtype, expr->byteorder, expr->len,
+ expr->hash.mod - 1);
return 0;
}