Blame SOURCES/0015-xtables-Review-nft_init.patch

2e3e3a
From 51f895d54af6e163e0290520e124e9413438ccf4 Mon Sep 17 00:00:00 2001
2e3e3a
From: Phil Sutter <phil@nwl.cc>
2e3e3a
Date: Fri, 21 Feb 2020 14:55:52 +0100
2e3e3a
Subject: [PATCH] xtables: Review nft_init()
2e3e3a
2e3e3a
Move common code into nft_init(), such as:
2e3e3a
2e3e3a
* initial zeroing nft_handle fields
2e3e3a
* family ops lookup and assignment to 'ops' field
2e3e3a
* setting of 'family' field
2e3e3a
2e3e3a
This requires minor adjustments in xtables_restore_main() so extra field
2e3e3a
initialization doesn't happen before nft_init() call.
2e3e3a
2e3e3a
As a side-effect, this fixes segfaulting xtables-monitor binary when
2e3e3a
printing rules for trace event as in that code-path 'ops' field wasn't
2e3e3a
initialized.
2e3e3a
2e3e3a
Signed-off-by: Phil Sutter <phil@nwl.cc>
2e3e3a
(cherry picked from commit d0446ab11182f6ca2adc486a124895f09a220c6e)
2e3e3a
Signed-off-by: Phil Sutter <psutter@redhat.com>
2e3e3a
---
2e3e3a
 iptables/nft.c                |  9 ++++++++-
2e3e3a
 iptables/nft.h                |  2 +-
2e3e3a
 iptables/xtables-arp.c        |  9 +--------
2e3e3a
 iptables/xtables-eb.c         |  9 +--------
2e3e3a
 iptables/xtables-monitor.c    |  2 +-
2e3e3a
 iptables/xtables-restore.c    | 14 +++++++-------
2e3e3a
 iptables/xtables-save.c       |  9 ++-------
2e3e3a
 iptables/xtables-standalone.c |  6 ++----
2e3e3a
 iptables/xtables-translate.c  |  2 +-
2e3e3a
 iptables/xtables.c            |  4 ----
2e3e3a
 10 files changed, 24 insertions(+), 42 deletions(-)
2e3e3a
2e3e3a
diff --git a/iptables/nft.c b/iptables/nft.c
2e3e3a
index 3f2a62ae12c07..0287add3fb21f 100644
2e3e3a
--- a/iptables/nft.c
2e3e3a
+++ b/iptables/nft.c
2e3e3a
@@ -789,8 +789,10 @@ int nft_restart(struct nft_handle *h)
2e3e3a
 	return 0;
2e3e3a
 }
2e3e3a
 
2e3e3a
-int nft_init(struct nft_handle *h, const struct builtin_table *t)
2e3e3a
+int nft_init(struct nft_handle *h, int family, const struct builtin_table *t)
2e3e3a
 {
2e3e3a
+	memset(h, 0, sizeof(*h));
2e3e3a
+
2e3e3a
 	h->nl = mnl_socket_open(NETLINK_NETFILTER);
2e3e3a
 	if (h->nl == NULL)
2e3e3a
 		return -1;
2e3e3a
@@ -800,9 +802,14 @@ int nft_init(struct nft_handle *h, const struct builtin_table *t)
2e3e3a
 		return -1;
2e3e3a
 	}
2e3e3a
 
2e3e3a
+	h->ops = nft_family_ops_lookup(family);
2e3e3a
+	if (!h->ops)
2e3e3a
+		xtables_error(PARAMETER_PROBLEM, "Unknown family");
2e3e3a
+
2e3e3a
 	h->portid = mnl_socket_get_portid(h->nl);
2e3e3a
 	h->tables = t;
2e3e3a
 	h->cache = &h->__cache[0];
2e3e3a
+	h->family = family;
2e3e3a
 
2e3e3a
 	INIT_LIST_HEAD(&h->obj_list);
2e3e3a
 	INIT_LIST_HEAD(&h->err_list);
2e3e3a
diff --git a/iptables/nft.h b/iptables/nft.h
2e3e3a
index 51b5660314c0c..5cf260a6d2cd3 100644
2e3e3a
--- a/iptables/nft.h
2e3e3a
+++ b/iptables/nft.h
2e3e3a
@@ -80,7 +80,7 @@ extern const struct builtin_table xtables_bridge[NFT_TABLE_MAX];
2e3e3a
 int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
2e3e3a
 	     int (*cb)(const struct nlmsghdr *nlh, void *data),
2e3e3a
 	     void *data);
2e3e3a
-int nft_init(struct nft_handle *h, const struct builtin_table *t);
2e3e3a
+int nft_init(struct nft_handle *h, int family, const struct builtin_table *t);
2e3e3a
 void nft_fini(struct nft_handle *h);
2e3e3a
 int nft_restart(struct nft_handle *h);
2e3e3a
 
2e3e3a
diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c
2e3e3a
index 9cfad76263d32..c8196f08baa59 100644
2e3e3a
--- a/iptables/xtables-arp.c
2e3e3a
+++ b/iptables/xtables-arp.c
2e3e3a
@@ -500,17 +500,10 @@ int nft_init_arp(struct nft_handle *h, const char *pname)
2e3e3a
 	init_extensionsa();
2e3e3a
 #endif
2e3e3a
 
2e3e3a
-	memset(h, 0, sizeof(*h));
2e3e3a
-	h->family = NFPROTO_ARP;
2e3e3a
-
2e3e3a
-	if (nft_init(h, xtables_arp) < 0)
2e3e3a
+	if (nft_init(h, NFPROTO_ARP, xtables_arp) < 0)
2e3e3a
 		xtables_error(OTHER_PROBLEM,
2e3e3a
 			      "Could not initialize nftables layer.");
2e3e3a
 
2e3e3a
-	h->ops = nft_family_ops_lookup(h->family);
2e3e3a
-	if (h->ops == NULL)
2e3e3a
-		xtables_error(PARAMETER_PROBLEM, "Unknown family");
2e3e3a
-
2e3e3a
 	return 0;
2e3e3a
 }
2e3e3a
 
2e3e3a
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
2e3e3a
index 15b971da3d425..c006bc95ac681 100644
2e3e3a
--- a/iptables/xtables-eb.c
2e3e3a
+++ b/iptables/xtables-eb.c
2e3e3a
@@ -739,16 +739,9 @@ int nft_init_eb(struct nft_handle *h, const char *pname)
2e3e3a
 	init_extensionsb();
2e3e3a
 #endif
2e3e3a
 
2e3e3a
-	memset(h, 0, sizeof(*h));
2e3e3a
-
2e3e3a
-	h->family = NFPROTO_BRIDGE;
2e3e3a
-
2e3e3a
-	if (nft_init(h, xtables_bridge) < 0)
2e3e3a
+	if (nft_init(h, NFPROTO_BRIDGE, xtables_bridge) < 0)
2e3e3a
 		xtables_error(OTHER_PROBLEM,
2e3e3a
 			      "Could not initialize nftables layer.");
2e3e3a
-	h->ops = nft_family_ops_lookup(h->family);
2e3e3a
-	if (!h->ops)
2e3e3a
-		xtables_error(PARAMETER_PROBLEM, "Unknown family");
2e3e3a
 
2e3e3a
 	/* manually registering ebt matches, given the original ebtables parser
2e3e3a
 	 * don't use '-m matchname' and the match can't be loaded dynamically when
2e3e3a
diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c
2e3e3a
index a5245d1422af9..c2b31dbaa0795 100644
2e3e3a
--- a/iptables/xtables-monitor.c
2e3e3a
+++ b/iptables/xtables-monitor.c
2e3e3a
@@ -615,7 +615,7 @@ int xtables_monitor_main(int argc, char *argv[])
2e3e3a
 	init_extensions4();
2e3e3a
 #endif
2e3e3a
 
2e3e3a
-	if (nft_init(&h, xtables_ipv4)) {
2e3e3a
+	if (nft_init(&h, AF_INET, xtables_ipv4)) {
2e3e3a
 		fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
2e3e3a
 			xtables_globals.program_name,
2e3e3a
 			xtables_globals.program_version,
2e3e3a
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
2e3e3a
index fb2ac8b5c12a3..11834c0ea98c5 100644
2e3e3a
--- a/iptables/xtables-restore.c
2e3e3a
+++ b/iptables/xtables-restore.c
2e3e3a
@@ -360,15 +360,13 @@ static int
2e3e3a
 xtables_restore_main(int family, const char *progname, int argc, char *argv[])
2e3e3a
 {
2e3e3a
 	const struct builtin_table *tables;
2e3e3a
-	struct nft_handle h = {
2e3e3a
-		.family = family,
2e3e3a
-		.restore = true,
2e3e3a
-	};
2e3e3a
-	int c;
2e3e3a
 	struct nft_xt_restore_parse p = {
2e3e3a
 		.commit = true,
2e3e3a
 		.cb = &restore_cb,
2e3e3a
 	};
2e3e3a
+	bool noflush = false;
2e3e3a
+	struct nft_handle h;
2e3e3a
+	int c;
2e3e3a
 
2e3e3a
 	line = 0;
2e3e3a
 
2e3e3a
@@ -402,7 +400,7 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[])
2e3e3a
 				print_usage(prog_name, PACKAGE_VERSION);
2e3e3a
 				exit(0);
2e3e3a
 			case 'n':
2e3e3a
-				h.noflush = 1;
2e3e3a
+				noflush = true;
2e3e3a
 				break;
2e3e3a
 			case 'M':
2e3e3a
 				xtables_modprobe_program = optarg;
2e3e3a
@@ -464,13 +462,15 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[])
2e3e3a
 		return 1;
2e3e3a
 	}
2e3e3a
 
2e3e3a
-	if (nft_init(&h, tables) < 0) {
2e3e3a
+	if (nft_init(&h, family, tables) < 0) {
2e3e3a
 		fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
2e3e3a
 				xtables_globals.program_name,
2e3e3a
 				xtables_globals.program_version,
2e3e3a
 				strerror(errno));
2e3e3a
 		exit(EXIT_FAILURE);
2e3e3a
 	}
2e3e3a
+	h.noflush = noflush;
2e3e3a
+	h.restore = true;
2e3e3a
 
2e3e3a
 	xtables_restore_parse(&h, &p);
2e3e3a
 
2e3e3a
diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c
2e3e3a
index 3a52f8c3d8209..228282deaed07 100644
2e3e3a
--- a/iptables/xtables-save.c
2e3e3a
+++ b/iptables/xtables-save.c
2e3e3a
@@ -139,10 +139,8 @@ xtables_save_main(int family, int argc, char *argv[],
2e3e3a
 	struct do_output_data d = {
2e3e3a
 		.format = FMT_NOCOUNTS,
2e3e3a
 	};
2e3e3a
+	struct nft_handle h;
2e3e3a
 	bool dump = false;
2e3e3a
-	struct nft_handle h = {
2e3e3a
-		.family	= family,
2e3e3a
-	};
2e3e3a
 	FILE *file = NULL;
2e3e3a
 	int ret, c;
2e3e3a
 
2e3e3a
@@ -242,16 +240,13 @@ xtables_save_main(int family, int argc, char *argv[],
2e3e3a
 		return 1;
2e3e3a
 	}
2e3e3a
 
2e3e3a
-	if (nft_init(&h, tables) < 0) {
2e3e3a
+	if (nft_init(&h, family, tables) < 0) {
2e3e3a
 		fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
2e3e3a
 				xtables_globals.program_name,
2e3e3a
 				xtables_globals.program_version,
2e3e3a
 				strerror(errno));
2e3e3a
 		exit(EXIT_FAILURE);
2e3e3a
 	}
2e3e3a
-	h.ops = nft_family_ops_lookup(h.family);
2e3e3a
-	if (!h.ops)
2e3e3a
-		xtables_error(PARAMETER_PROBLEM, "Unknown family");
2e3e3a
 
2e3e3a
 	ret = do_output(&h, tablename, &d);
2e3e3a
 	nft_fini(&h);
2e3e3a
diff --git a/iptables/xtables-standalone.c b/iptables/xtables-standalone.c
2e3e3a
index 1a28c5480629f..022d5dd44abbf 100644
2e3e3a
--- a/iptables/xtables-standalone.c
2e3e3a
+++ b/iptables/xtables-standalone.c
2e3e3a
@@ -44,9 +44,7 @@ xtables_main(int family, const char *progname, int argc, char *argv[])
2e3e3a
 {
2e3e3a
 	int ret;
2e3e3a
 	char *table = "filter";
2e3e3a
-	struct nft_handle h = {
2e3e3a
-		.family = family,
2e3e3a
-	};
2e3e3a
+	struct nft_handle h;
2e3e3a
 
2e3e3a
 	xtables_globals.program_name = progname;
2e3e3a
 	ret = xtables_init_all(&xtables_globals, family);
2e3e3a
@@ -61,7 +59,7 @@ xtables_main(int family, const char *progname, int argc, char *argv[])
2e3e3a
 	init_extensions4();
2e3e3a
 #endif
2e3e3a
 
2e3e3a
-	if (nft_init(&h, xtables_ipv4) < 0) {
2e3e3a
+	if (nft_init(&h, family, xtables_ipv4) < 0) {
2e3e3a
 		fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
2e3e3a
 				xtables_globals.program_name,
2e3e3a
 				xtables_globals.program_version,
2e3e3a
diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c
2e3e3a
index 0f95855b41aa4..76ad7eb69eca9 100644
2e3e3a
--- a/iptables/xtables-translate.c
2e3e3a
+++ b/iptables/xtables-translate.c
2e3e3a
@@ -480,7 +480,7 @@ static int xtables_xlate_main_common(struct nft_handle *h,
2e3e3a
 		return 1;
2e3e3a
 	}
2e3e3a
 
2e3e3a
-	if (nft_init(h, tables) < 0) {
2e3e3a
+	if (nft_init(h, family, tables) < 0) {
2e3e3a
 		fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
2e3e3a
 				xtables_globals.program_name,
2e3e3a
 				xtables_globals.program_version,
2e3e3a
diff --git a/iptables/xtables.c b/iptables/xtables.c
2e3e3a
index 8f9dc628d0029..4b24d15c46295 100644
2e3e3a
--- a/iptables/xtables.c
2e3e3a
+++ b/iptables/xtables.c
2e3e3a
@@ -571,10 +571,6 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
2e3e3a
 	   demand-load a protocol. */
2e3e3a
 	opterr = 0;
2e3e3a
 
2e3e3a
-	h->ops = nft_family_ops_lookup(h->family);
2e3e3a
-	if (h->ops == NULL)
2e3e3a
-		xtables_error(PARAMETER_PROBLEM, "Unknown family");
2e3e3a
-
2e3e3a
 	opts = xt_params->orig_opts;
2e3e3a
 	while ((cs->c = getopt_long(argc, argv,
2e3e3a
 	   "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvw::W::nt:m:xc:g:46",
2e3e3a
-- 
2e3e3a
2.26.2
2e3e3a