diff mbox series

[iptables,2/3] libxtables: Introduce 'matchmask' target callback

Message ID 20200512171018.16871-3-phil@nwl.cc
State Under Review
Delegated to: Pablo Neira
Headers show
Series Fix SECMARK target comparison | expand

Commit Message

Phil Sutter May 12, 2020, 5:10 p.m. UTC
In order to support customized target data comparison, introduce a
callback which sets the matchmask used by libiptc's target_same()
function for the per-target part.

If defined, use this function in both legacy and nft variants.

Since this changes struct xtables_target, bump libxtables current and
reset age to zero.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 configure.ac          |  4 ++--
 include/xtables.h     |  3 +++
 iptables/nft-shared.c | 15 ++++++++++++++-
 iptables/xshared.c    | 10 +++++++---
 4 files changed, 26 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/configure.ac b/configure.ac
index 02f6481ca52ed..5e330f3388de2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,8 +2,8 @@ 
 AC_INIT([iptables], [1.8.4])
 
 # See libtool.info "Libtool's versioning system"
-libxtables_vcurrent=15
-libxtables_vage=3
+libxtables_vcurrent=16
+libxtables_vage=0
 
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_HEADERS([config.h])
diff --git a/include/xtables.h b/include/xtables.h
index 5044dd08e86d3..9483486bf7bae 100644
--- a/include/xtables.h
+++ b/include/xtables.h
@@ -356,6 +356,9 @@  struct xtables_target {
 	/* Print target name or alias */
 	const char *(*alias)(const struct xt_entry_target *target);
 
+	/* fill matchmask of size userspacesize */
+	void (*matchmask)(void *mask);
+
 	/* Pointer to list of extra command-line options */
 	const struct option *extra_opts;
 
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index c5a8f3fcc051d..d2c252a3081b0 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -968,8 +968,21 @@  bool compare_targets(struct xtables_target *tg1, struct xtables_target *tg2)
 	if (strcmp(tg1->t->u.user.name, tg2->t->u.user.name) != 0)
 		return false;
 
-	if (memcmp(tg1->t->data, tg2->t->data, tg1->userspacesize) != 0)
+	if (tg1->matchmask) {
+		char *mask = xtables_malloc(tg1->userspacesize);
+		int i;
+
+		tg1->matchmask(mask);
+		for (i = 0; i < tg1->userspacesize; i++) {
+			if ((tg1->t->data[i] ^ tg2->t->data[i]) & mask[i]) {
+				free(mask);
+				return false;
+			}
+		}
+		free(mask);
+	} else if (memcmp(tg1->t->data, tg2->t->data, tg1->userspacesize)) {
 		return false;
+	}
 
 	return true;
 }
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 2438c4eeb5ff7..d938fc5d1f9e2 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -802,9 +802,13 @@  make_delete_mask(const struct xtables_rule_match *matches,
 		mptr += XT_ALIGN(sizeof(struct xt_entry_match)) + matchp->match->size;
 	}
 
-	memset(mptr, 0xFF,
-	       XT_ALIGN(sizeof(struct xt_entry_target))
-	       + target->userspacesize);
+	memset(mptr, 0xFF, XT_ALIGN(sizeof(struct xt_entry_target)));
+	mptr += XT_ALIGN(sizeof(struct xt_entry_target));
+
+	if (target->matchmask)
+		target->matchmask(mptr);
+	else
+		memset(mptr, 0xFF, target->userspacesize);
 
 	return mask;
 }