Blame SOURCES/0024-nft-Fix-for-F-in-iptables-dumps.patch

598666
From 8ae56bbaa4119bdcf1d6abc8b78f21490657983c Mon Sep 17 00:00:00 2001
598666
From: Phil Sutter <phil@nwl.cc>
598666
Date: Fri, 24 Apr 2020 11:32:08 +0200
598666
Subject: [PATCH] nft: Fix for '-F' in iptables dumps
598666
598666
When restoring a dump which contains an explicit flush command,
598666
previously added rules are removed from cache and the following commit
598666
will try to create netlink messages based on freed memory.
598666
598666
Fix this by weeding any rule-based commands from obj_list if they
598666
address the same chain.
598666
598666
Signed-off-by: Phil Sutter <phil@nwl.cc>
598666
(cherry picked from commit 5bd3ab5c778033877d44a0c619ef6f98f34516af)
598666
Signed-off-by: Phil Sutter <psutter@redhat.com>
598666
---
598666
 iptables/nft.c | 34 ++++++++++++++++++++++++++++++++++
598666
 1 file changed, 34 insertions(+)
598666
598666
diff --git a/iptables/nft.c b/iptables/nft.c
598666
index 4930b6de534d8..e95e99f1d8d71 100644
598666
--- a/iptables/nft.c
598666
+++ b/iptables/nft.c
598666
@@ -411,6 +411,38 @@ batch_rule_add(struct nft_handle *h, enum obj_update_type type,
598666
 	return batch_add(h, type, r);
598666
 }
598666
 
598666
+static void batch_obj_del(struct nft_handle *h, struct obj_update *o);
598666
+
598666
+static void batch_chain_flush(struct nft_handle *h,
598666
+			      const char *table, const char *chain)
598666
+{
598666
+	struct obj_update *obj, *tmp;
598666
+
598666
+	list_for_each_entry_safe(obj, tmp, &h->obj_list, head) {
598666
+		struct nftnl_rule *r = obj->ptr;
598666
+
598666
+		switch (obj->type) {
598666
+		case NFT_COMPAT_RULE_APPEND:
598666
+		case NFT_COMPAT_RULE_INSERT:
598666
+		case NFT_COMPAT_RULE_REPLACE:
598666
+		case NFT_COMPAT_RULE_DELETE:
598666
+			break;
598666
+		default:
598666
+			continue;
598666
+		}
598666
+
598666
+		if (table &&
598666
+		    strcmp(table, nftnl_rule_get_str(r, NFTNL_RULE_TABLE)))
598666
+			continue;
598666
+
598666
+		if (chain &&
598666
+		    strcmp(chain, nftnl_rule_get_str(r, NFTNL_RULE_CHAIN)))
598666
+			continue;
598666
+
598666
+		batch_obj_del(h, obj);
598666
+	}
598666
+}
598666
+
598666
 const struct builtin_table xtables_ipv4[NFT_TABLE_MAX] = {
598666
 	[NFT_TABLE_RAW] = {
598666
 		.name	= "raw",
598666
@@ -1671,6 +1703,7 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table,
598666
 	}
598666
 
598666
 	if (chain || !verbose) {
598666
+		batch_chain_flush(h, table, chain);
598666
 		__nft_rule_flush(h, table, chain, verbose, false);
598666
 		flush_rule_cache(h, table, c);
598666
 		return 1;
598666
@@ -1686,6 +1719,7 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table,
598666
 	while (c != NULL) {
598666
 		chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
598666
 
598666
+		batch_chain_flush(h, table, chain);
598666
 		__nft_rule_flush(h, table, chain, verbose, false);
598666
 		flush_rule_cache(h, table, c);
598666
 		c = nftnl_chain_list_iter_next(iter);
598666
-- 
598666
2.27.0
598666