Blob Blame History Raw
From 40edcc35cbfca22d4cb471464eacc12cf7c5c28a Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Wed, 3 Oct 2018 12:09:09 +0200
Subject: [PATCH] segtree: disantangle get_set_interval_end()

This function overrides the left pointer. Instead update this function
to return the range that we found to enclose the left element. Note that
we may not find a closing right element - therefore, it is a standalone
element - in that case this function returns NULL.

Reported-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
(cherry picked from commit 33eb4594a1c764776a46b48bc1a7d726b561359d)
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
 src/segtree.c | 37 ++++++++++++++++++++++---------------
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/src/segtree.c b/src/segtree.c
index 288b01f420a48..0d53c83fd837e 100644
--- a/src/segtree.c
+++ b/src/segtree.c
@@ -681,9 +681,9 @@ static struct expr *get_set_interval_end(const struct table *table,
 					 const char *set_name,
 					 struct expr *left)
 {
+	struct expr *i, *range = NULL;
 	struct set *set;
 	mpz_t low, high;
-	struct expr *i;
 
 	set = set_lookup(table, set_name);
 	mpz_init2(low, set->key->len);
@@ -694,9 +694,9 @@ static struct expr *get_set_interval_end(const struct table *table,
 		case EXPR_RANGE:
 			range_expr_value_low(low, i);
 			if (mpz_cmp(low, left->key->value) == 0) {
-				left = range_expr_alloc(&internal_location,
-							expr_clone(left->key),
-							expr_clone(i->key->right));
+				range = range_expr_alloc(&internal_location,
+							 expr_clone(left->key),
+							 expr_clone(i->key->right));
 				break;
 			}
 			break;
@@ -708,12 +708,12 @@ static struct expr *get_set_interval_end(const struct table *table,
 	mpz_clear(low);
 	mpz_clear(high);
 
-	return left;
+	return range;
 }
 
 int get_set_decompose(struct table *table, struct set *set)
 {
-	struct expr *i, *next, *new;
+	struct expr *i, *next, *range;
 	struct expr *left = NULL;
 	struct expr *new_init;
 
@@ -724,28 +724,35 @@ int get_set_decompose(struct table *table, struct set *set)
 			list_del(&left->list);
 			list_del(&i->list);
 			mpz_sub_ui(i->key->value, i->key->value, 1);
-			new = get_set_interval_find(table, set->handle.set.name,
+			range = get_set_interval_find(table, set->handle.set.name,
 						    left, i);
-			if (!new) {
+			if (!range) {
 				errno = ENOENT;
 				return -1;
 			}
 
-			compound_expr_add(new_init, new);
+			compound_expr_add(new_init, range);
 			left = NULL;
 		} else {
 			if (left) {
-				left = get_set_interval_end(table,
-							    set->handle.set.name,
-							    left);
-				compound_expr_add(new_init, left);
+				range = get_set_interval_end(table,
+							     set->handle.set.name,
+							     left);
+				if (range)
+					compound_expr_add(new_init, range);
+				else
+					compound_expr_add(new_init,
+							  expr_clone(left));
 			}
 			left = i;
 		}
 	}
 	if (left) {
-		left = get_set_interval_end(table, set->handle.set.name, left);
-		compound_expr_add(new_init, left);
+		range = get_set_interval_end(table, set->handle.set.name, left);
+		if (range)
+			compound_expr_add(new_init, left);
+		else
+			compound_expr_add(new_init, expr_clone(left));
 	}
 
 	set->init = new_init;
-- 
2.21.0