summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2018-10-17 12:31:22 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2018-10-17 12:55:44 +0200
commit6340734d7034d2424d3a5e34c3042c97a63b8b2d (patch)
treeedb70dcfcd9e1e8ec9cfc11efa5b513923643670
parentb274c169014e71715f9333ee028c5a9304881919 (diff)
evaluate: bogus bail out with raw expression from dynamic sets
The following ruleset that uses raw expressions: table ip nftlb { map persistency { type inet_service : mark size 65535 timeout 1h elements = { 53 expires 59m55s864ms : 0x00000064, 80 expires 59m58s924ms : 0x00000065, 443 expires 59m56s220ms : 0x00000064 } } chain pre { type filter hook prerouting priority filter; policy accept; ip protocol { tcp, udp } update @persistencia { @th,0,16 : numgen inc mod 2 offset 100 } } } bogusly bails out with: /tmp/test:9:57-64: Error: datatype mismatch: expected internet network service, expression has type integer ip protocol { tcp, udp } update @persistencia { @th,0,16 : numgen inc mod 2 offset 100 } ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Fix the problem by evaluating expression basetype and length in this case. Reported-by: Laura Garcia <nevola@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/datatype.h6
-rw-r--r--src/evaluate.c12
2 files changed, 17 insertions, 1 deletions
diff --git a/include/datatype.h b/include/datatype.h
index eab505ba..f7092f06 100644
--- a/include/datatype.h
+++ b/include/datatype.h
@@ -171,6 +171,12 @@ static inline bool datatype_equal(const struct datatype *d1,
return d1->type == d2->type;
}
+static inline const struct datatype *
+datatype_basetype(const struct datatype *dtype)
+{
+ return dtype->basetype ? dtype->basetype : dtype;
+}
+
/**
* struct symbolic_constant - symbol <-> constant mapping
*
diff --git a/src/evaluate.c b/src/evaluate.c
index db49a18d..1880578b 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1854,7 +1854,17 @@ static int stmt_evaluate_arg(struct eval_ctx *ctx, struct stmt *stmt,
if (expr_evaluate(ctx, expr) < 0)
return -1;
- if (!datatype_equal((*expr)->dtype, dtype))
+ if ((*expr)->ops->type == EXPR_PAYLOAD &&
+ (*expr)->dtype->type == TYPE_INTEGER &&
+ ((*expr)->dtype->type != datatype_basetype(dtype)->type ||
+ (*expr)->len != len))
+ return stmt_binary_error(ctx, *expr, stmt,
+ "datatype mismatch: expected %s, "
+ "expression has type %s with length %d",
+ dtype->desc, (*expr)->dtype->desc,
+ (*expr)->len);
+ else if ((*expr)->dtype->type != TYPE_INTEGER &&
+ !datatype_equal((*expr)->dtype, dtype))
return stmt_binary_error(ctx, *expr, stmt,
"datatype mismatch: expected %s, "
"expression has type %s",