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

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