|
|
19e5f4 |
From 785823a1f607a7bcd32d4cb42655422c223fcad5 Mon Sep 17 00:00:00 2001
|
|
|
19e5f4 |
From: Phil Sutter <psutter@redhat.com>
|
|
|
19e5f4 |
Date: Mon, 7 Dec 2020 18:25:20 +0100
|
|
|
19e5f4 |
Subject: [PATCH] evaluate: Perform set evaluation on implicitly declared
|
|
|
19e5f4 |
(anonymous) sets
|
|
|
19e5f4 |
|
|
|
19e5f4 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1877022
|
|
|
19e5f4 |
Upstream Status: nftables commit 7aa08d45031ec
|
|
|
19e5f4 |
|
|
|
19e5f4 |
commit 7aa08d45031ec7ce5dadb4979471d626367c09cd
|
|
|
19e5f4 |
Author: Stefano Brivio <sbrivio@redhat.com>
|
|
|
19e5f4 |
Date: Wed May 27 22:51:21 2020 +0200
|
|
|
19e5f4 |
|
|
|
19e5f4 |
evaluate: Perform set evaluation on implicitly declared (anonymous) sets
|
|
|
19e5f4 |
|
|
|
19e5f4 |
If a set is implicitly declared, set_evaluate() is not called as a
|
|
|
19e5f4 |
result of cmd_evaluate_add(), because we're adding in fact something
|
|
|
19e5f4 |
else (e.g. a rule). Expression-wise, evaluation still happens as the
|
|
|
19e5f4 |
implicit set expression is eventually found in the tree and handled
|
|
|
19e5f4 |
by expr_evaluate_set(), but context-wise evaluation (set_evaluate())
|
|
|
19e5f4 |
is skipped, and this might be relevant instead.
|
|
|
19e5f4 |
|
|
|
19e5f4 |
This is visible in the reported case of an anonymous set including
|
|
|
19e5f4 |
concatenated ranges:
|
|
|
19e5f4 |
|
|
|
19e5f4 |
# nft add rule t c ip saddr . tcp dport { 192.0.2.1 . 20-30 } accept
|
|
|
19e5f4 |
BUG: invalid range expression type concat
|
|
|
19e5f4 |
nft: expression.c:1160: range_expr_value_low: Assertion `0' failed.
|
|
|
19e5f4 |
Aborted
|
|
|
19e5f4 |
|
|
|
19e5f4 |
because we reach do_add_set() without properly evaluated flags and
|
|
|
19e5f4 |
set description, and eventually end up in expr_to_intervals(), which
|
|
|
19e5f4 |
can't handle that expression.
|
|
|
19e5f4 |
|
|
|
19e5f4 |
Explicitly call set_evaluate() as we add anonymous sets into the
|
|
|
19e5f4 |
context, and instruct the same function to:
|
|
|
19e5f4 |
- skip expression-wise set evaluation if the set is anonymous, as
|
|
|
19e5f4 |
that happens later anyway as part of the general tree evaluation
|
|
|
19e5f4 |
- skip the insertion in the set cache, as it makes no sense to have
|
|
|
19e5f4 |
sets that shouldn't be referenced there
|
|
|
19e5f4 |
|
|
|
19e5f4 |
For object maps, the allocation of the expression for set->data is
|
|
|
19e5f4 |
already handled by set_evaluate(), so we can now drop that from
|
|
|
19e5f4 |
stmt_evaluate_objref_map().
|
|
|
19e5f4 |
|
|
|
19e5f4 |
v2:
|
|
|
19e5f4 |
- skip insertion of set in cache (Pablo Neira Ayuso)
|
|
|
19e5f4 |
- drop double allocation of expression (and leak of the first
|
|
|
19e5f4 |
one) for object maps (Pablo Neira Ayuso)
|
|
|
19e5f4 |
|
|
|
19e5f4 |
Reported-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
19e5f4 |
Reported-by: Phil Sutter <phil@nwl.cc>
|
|
|
19e5f4 |
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
|
|
|
19e5f4 |
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
19e5f4 |
---
|
|
|
19e5f4 |
src/evaluate.c | 20 ++++++++++----------
|
|
|
19e5f4 |
1 file changed, 10 insertions(+), 10 deletions(-)
|
|
|
19e5f4 |
|
|
|
19e5f4 |
diff --git a/src/evaluate.c b/src/evaluate.c
|
|
|
19e5f4 |
index 578dcae..fc45cef 100644
|
|
|
19e5f4 |
--- a/src/evaluate.c
|
|
|
19e5f4 |
+++ b/src/evaluate.c
|
|
|
19e5f4 |
@@ -75,6 +75,7 @@ static void key_fix_dtype_byteorder(struct expr *key)
|
|
|
19e5f4 |
datatype_set(key, set_datatype_alloc(dtype, key->byteorder));
|
|
|
19e5f4 |
}
|
|
|
19e5f4 |
|
|
|
19e5f4 |
+static int set_evaluate(struct eval_ctx *ctx, struct set *set);
|
|
|
19e5f4 |
static struct expr *implicit_set_declaration(struct eval_ctx *ctx,
|
|
|
19e5f4 |
const char *name,
|
|
|
19e5f4 |
struct expr *key,
|
|
|
19e5f4 |
@@ -105,6 +106,8 @@ static struct expr *implicit_set_declaration(struct eval_ctx *ctx,
|
|
|
19e5f4 |
list_add_tail(&cmd->list, &ctx->cmd->list);
|
|
|
19e5f4 |
}
|
|
|
19e5f4 |
|
|
|
19e5f4 |
+ set_evaluate(ctx, set);
|
|
|
19e5f4 |
+
|
|
|
19e5f4 |
return set_ref_expr_alloc(&expr->location, set);
|
|
|
19e5f4 |
}
|
|
|
19e5f4 |
|
|
|
19e5f4 |
@@ -3171,12 +3174,6 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt)
|
|
|
19e5f4 |
|
|
|
19e5f4 |
mappings = implicit_set_declaration(ctx, "__objmap%d",
|
|
|
19e5f4 |
key, mappings);
|
|
|
19e5f4 |
-
|
|
|
19e5f4 |
- mappings->set->data = constant_expr_alloc(&netlink_location,
|
|
|
19e5f4 |
- &string_type,
|
|
|
19e5f4 |
- BYTEORDER_HOST_ENDIAN,
|
|
|
19e5f4 |
- NFT_OBJ_MAXNAMELEN * BITS_PER_BYTE,
|
|
|
19e5f4 |
- NULL);
|
|
|
19e5f4 |
mappings->set->objtype = stmt->objref.type;
|
|
|
19e5f4 |
|
|
|
19e5f4 |
map->mappings = mappings;
|
|
|
19e5f4 |
@@ -3381,6 +3378,13 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
|
|
|
19e5f4 |
|
|
|
19e5f4 |
}
|
|
|
19e5f4 |
|
|
|
19e5f4 |
+ /* Default timeout value implies timeout support */
|
|
|
19e5f4 |
+ if (set->timeout)
|
|
|
19e5f4 |
+ set->flags |= NFT_SET_TIMEOUT;
|
|
|
19e5f4 |
+
|
|
|
19e5f4 |
+ if (set_is_anonymous(set->flags))
|
|
|
19e5f4 |
+ return 0;
|
|
|
19e5f4 |
+
|
|
|
19e5f4 |
ctx->set = set;
|
|
|
19e5f4 |
if (set->init != NULL) {
|
|
|
19e5f4 |
expr_set_context(&ctx->ectx, set->key->dtype, set->key->len);
|
|
|
19e5f4 |
@@ -3392,10 +3396,6 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
|
|
|
19e5f4 |
if (set_lookup(table, set->handle.set.name) == NULL)
|
|
|
19e5f4 |
set_add_hash(set_get(set), table);
|
|
|
19e5f4 |
|
|
|
19e5f4 |
- /* Default timeout value implies timeout support */
|
|
|
19e5f4 |
- if (set->timeout)
|
|
|
19e5f4 |
- set->flags |= NFT_SET_TIMEOUT;
|
|
|
19e5f4 |
-
|
|
|
19e5f4 |
return 0;
|
|
|
19e5f4 |
}
|
|
|
19e5f4 |
|
|
|
19e5f4 |
--
|
|
|
bfbb76 |
2.31.1
|
|
|
19e5f4 |
|