Blame SOURCES/0036-libxtables-Simplify-pending-extension-registration.patch

87db66
From 1a842fb1cfb3b36f3081aee37c5fdd4a897d77d5 Mon Sep 17 00:00:00 2001
87db66
From: Phil Sutter <phil@nwl.cc>
87db66
Date: Fri, 18 Sep 2020 18:48:14 +0200
87db66
Subject: [PATCH] libxtables: Simplify pending extension registration
87db66
87db66
Assuming that pending extensions are sorted by first name and family,
87db66
then descending revision, the decision where to insert a newly
87db66
registered extension may be simplified by memorizing the previous
87db66
registration (which obviously is of same name and family and higher
87db66
revision).
87db66
87db66
As a side-effect, fix for unsupported old extension revisions lingering
87db66
in pending extension list forever and being retried with every use of
87db66
the given extension. Any revision being rejected by the kernel may
87db66
safely be dropped iff a previous (read: higher) revision was accepted
87db66
already.
87db66
87db66
Yet another side-effect of this change is the removal of an unwanted
87db66
recursion by xtables_fully_register_pending_*() into itself via
87db66
xtables_find_*().
87db66
87db66
Signed-off-by: Phil Sutter <phil@nwl.cc>
87db66
(cherry picked from commit a1eaaceb0460b338294e40bdd5bc5186320a478c)
87db66
Signed-off-by: Phil Sutter <psutter@redhat.com>
87db66
---
87db66
 libxtables/xtables.c | 128 +++++++++++--------------------------------
87db66
 1 file changed, 33 insertions(+), 95 deletions(-)
87db66
87db66
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
87db66
index 13139d7f8ad62..409128333e0e6 100644
87db66
--- a/libxtables/xtables.c
87db66
+++ b/libxtables/xtables.c
87db66
@@ -203,8 +203,10 @@ struct xtables_match *xtables_matches;
87db66
 struct xtables_target *xtables_targets;
87db66
 
87db66
 /* Fully register a match/target which was previously partially registered. */
87db66
-static bool xtables_fully_register_pending_match(struct xtables_match *me);
87db66
-static bool xtables_fully_register_pending_target(struct xtables_target *me);
87db66
+static bool xtables_fully_register_pending_match(struct xtables_match *me,
87db66
+						 struct xtables_match *prev);
87db66
+static bool xtables_fully_register_pending_target(struct xtables_target *me,
87db66
+						  struct xtables_target *prev);
87db66
 
87db66
 void xtables_init(void)
87db66
 {
87db66
@@ -616,6 +618,7 @@ struct xtables_match *
87db66
 xtables_find_match(const char *name, enum xtables_tryload tryload,
87db66
 		   struct xtables_rule_match **matches)
87db66
 {
87db66
+	struct xtables_match *prev = NULL;
87db66
 	struct xtables_match **dptr;
87db66
 	struct xtables_match *ptr;
87db66
 	const char *icmp6 = "icmp6";
87db66
@@ -637,8 +640,12 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
87db66
 		if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) {
87db66
 			ptr = *dptr;
87db66
 			*dptr = (*dptr)->next;
87db66
-			if (xtables_fully_register_pending_match(ptr))
87db66
+			if (xtables_fully_register_pending_match(ptr, prev)) {
87db66
+				prev = ptr;
87db66
 				continue;
87db66
+			} else if (prev) {
87db66
+				continue;
87db66
+			}
87db66
 			*dptr = ptr;
87db66
 		}
87db66
 		dptr = &((*dptr)->next);
87db66
@@ -732,6 +739,7 @@ xtables_find_match_revision(const char *name, enum xtables_tryload tryload,
87db66
 struct xtables_target *
87db66
 xtables_find_target(const char *name, enum xtables_tryload tryload)
87db66
 {
87db66
+	struct xtables_target *prev = NULL;
87db66
 	struct xtables_target **dptr;
87db66
 	struct xtables_target *ptr;
87db66
 
87db66
@@ -748,8 +756,12 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
87db66
 		if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) {
87db66
 			ptr = *dptr;
87db66
 			*dptr = (*dptr)->next;
87db66
-			if (xtables_fully_register_pending_target(ptr))
87db66
+			if (xtables_fully_register_pending_target(ptr, prev)) {
87db66
+				prev = ptr;
87db66
 				continue;
87db66
+			} else if (prev) {
87db66
+				continue;
87db66
+			}
87db66
 			*dptr = ptr;
87db66
 		}
87db66
 		dptr = &((*dptr)->next);
87db66
@@ -1052,64 +1064,27 @@ static int xtables_target_prefer(const struct xtables_target *a,
87db66
 				 b->revision, b->family);
87db66
 }
87db66
 
87db66
-static bool xtables_fully_register_pending_match(struct xtables_match *me)
87db66
+static bool xtables_fully_register_pending_match(struct xtables_match *me,
87db66
+						 struct xtables_match *prev)
87db66
 {
87db66
-	struct xtables_match **i, *old, *pos = NULL;
87db66
+	struct xtables_match **i;
87db66
 	const char *rn;
87db66
-	int compare;
87db66
 
87db66
 	/* See if new match can be used. */
87db66
 	rn = (me->real_name != NULL) ? me->real_name : me->name;
87db66
 	if (!compatible_match_revision(rn, me->revision))
87db66
 		return false;
87db66
 
87db66
-	old = xtables_find_match(me->name, XTF_DURING_LOAD, NULL);
87db66
-	while (old) {
87db66
-		compare = xtables_match_prefer(old, me);
87db66
-		if (compare == 0) {
87db66
-			fprintf(stderr,
87db66
-				"%s: match `%s' already registered.\n",
87db66
-				xt_params->program_name, me->name);
87db66
-			exit(1);
87db66
-		}
87db66
-
87db66
-		/* Now we have two (or more) options, check compatibility. */
87db66
-		rn = (old->real_name != NULL) ? old->real_name : old->name;
87db66
-		if (compare > 0) {
87db66
-			/* Kernel tells old isn't compatible anymore??? */
87db66
-			if (!compatible_match_revision(rn, old->revision)) {
87db66
-				/* Delete old one. */
87db66
-				for (i = &xtables_matches; *i != old;)
87db66
-				     i = &(*i)->next;
87db66
-				*i = old->next;
87db66
-			}
87db66
-			pos = old;
87db66
-			old = old->next;
87db66
-			if (!old)
87db66
-				break;
87db66
-			if (!extension_cmp(me->name, old->name, old->family))
87db66
-				break;
87db66
-			continue;
87db66
-		}
87db66
-
87db66
-		/* Found right old */
87db66
-		pos = old;
87db66
-		break;
87db66
-	}
87db66
-
87db66
-	if (!pos) {
87db66
+	if (!prev) {
87db66
 		/* Append to list. */
87db66
 		for (i = &xtables_matches; *i; i = &(*i)->next);
87db66
-	} else if (compare < 0) {
87db66
-		/* Prepend it */
87db66
-		for (i = &xtables_matches; *i != pos; i = &(*i)->next);
87db66
-	} else if (compare > 0) {
87db66
+	} else {
87db66
 		/* Append it */
87db66
-		i = &pos->next;
87db66
-		pos = pos->next;
87db66
+		i = &prev->next;
87db66
+		prev = prev->next;
87db66
 	}
87db66
 
87db66
-	me->next = pos;
87db66
+	me->next = prev;
87db66
 	*i = me;
87db66
 
87db66
 	me->m = NULL;
87db66
@@ -1214,11 +1189,11 @@ void xtables_register_target(struct xtables_target *me)
87db66
 #endif
87db66
 }
87db66
 
87db66
-static bool xtables_fully_register_pending_target(struct xtables_target *me)
87db66
+static bool xtables_fully_register_pending_target(struct xtables_target *me,
87db66
+						  struct xtables_target *prev)
87db66
 {
87db66
-	struct xtables_target **i, *old, *pos = NULL;
87db66
+	struct xtables_target **i;
87db66
 	const char *rn;
87db66
-	int compare;
87db66
 
87db66
 	if (strcmp(me->name, "standard") != 0) {
87db66
 		/* See if new target can be used. */
87db66
@@ -1227,54 +1202,17 @@ static bool xtables_fully_register_pending_target(struct xtables_target *me)
87db66
 			return false;
87db66
 	}
87db66
 
87db66
-	old = xtables_find_target(me->name, XTF_DURING_LOAD);
87db66
-	while (old) {
87db66
-		compare = xtables_target_prefer(old, me);
87db66
-		if (compare == 0) {
87db66
-			fprintf(stderr,
87db66
-				"%s: target `%s' already registered.\n",
87db66
-				xt_params->program_name, me->name);
87db66
-			exit(1);
87db66
-		}
87db66
-
87db66
-		/* Now we have two (or more) options, check compatibility. */
87db66
-		rn = (old->real_name != NULL) ? old->real_name : old->name;
87db66
-		if (compare > 0) {
87db66
-			/* Kernel tells old isn't compatible anymore??? */
87db66
-			if (!compatible_target_revision(rn, old->revision)) {
87db66
-				/* Delete old one. */
87db66
-				for (i = &xtables_targets; *i != old;)
87db66
-				     i = &(*i)->next;
87db66
-				*i = old->next;
87db66
-			}
87db66
-			pos = old;
87db66
-			old = old->next;
87db66
-			if (!old)
87db66
-				break;
87db66
-			if (!extension_cmp(me->name, old->name, old->family))
87db66
-				break;
87db66
-			continue;
87db66
-		}
87db66
-
87db66
-		/* Found right old */
87db66
-		pos = old;
87db66
-		break;
87db66
-	}
87db66
-
87db66
-	if (!pos) {
87db66
+	if (!prev) {
87db66
 		/* Prepend to list. */
87db66
 		i = &xtables_targets;
87db66
-		pos = xtables_targets;
87db66
-	} else if (compare < 0) {
87db66
-		/* Prepend it */
87db66
-		for (i = &xtables_targets; *i != pos; i = &(*i)->next);
87db66
-	} else if (compare > 0) {
87db66
+		prev = xtables_targets;
87db66
+	} else {
87db66
 		/* Append it */
87db66
-		i = &pos->next;
87db66
-		pos = pos->next;
87db66
+		i = &prev->next;
87db66
+		prev = prev->next;
87db66
 	}
87db66
 
87db66
-	me->next = pos;
87db66
+	me->next = prev;
87db66
 	*i = me;
87db66
 
87db66
 	me->t = NULL;
87db66
-- 
87db66
2.28.0
87db66