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

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