Blame SOURCES/0033-evaluate-Perform-set-evaluation-on-implicitly-declar.patch

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
-- 
19e5f4
1.8.3.1
19e5f4