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

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