From 23992e9a26bfd760ff25ca6779d7f05eeb34877f Mon Sep 17 00:00:00 2001 From: eabdullin Date: Wed, 22 May 2024 13:35:31 +0000 Subject: [PATCH] import UBI firewalld-0.9.11-4.el8 --- ...-exception-on-overlap-checking-empty.patch | 32 ++++ ...pset-verify-remove-entries-from-file.patch | 48 ++++++ ...-fix-configuring-IP-range-for-ipsets.patch | 138 ++++++++++++++++++ ...ore-nftables-add-delete-table-helper.patch | 45 ++++++ ...les-always-flush-main-table-on-start.patch | 38 +++++ ...nUpOnExit-verify-restart-does-not-du.patch | 82 +++++++++++ ...ables-policy-use-delete-table-helper.patch | 32 ++++ SPECS/firewalld.spec | 18 ++- 8 files changed, 432 insertions(+), 1 deletion(-) create mode 100644 SOURCES/0011-v1.1.0-fix-ipset-exception-on-overlap-checking-empty.patch create mode 100644 SOURCES/0012-v1.1.0-test-ipset-verify-remove-entries-from-file.patch create mode 100644 SOURCES/0013-v1.2.0-fix-ipset-fix-configuring-IP-range-for-ipsets.patch create mode 100644 SOURCES/0014-v1.2.0-chore-nftables-add-delete-table-helper.patch create mode 100644 SOURCES/0015-v1.2.0-fix-nftables-always-flush-main-table-on-start.patch create mode 100644 SOURCES/0016-v1.2.0-test-CleanUpOnExit-verify-restart-does-not-du.patch create mode 100644 SOURCES/0017-v1.2.0-chore-nftables-policy-use-delete-table-helper.patch diff --git a/SOURCES/0011-v1.1.0-fix-ipset-exception-on-overlap-checking-empty.patch b/SOURCES/0011-v1.1.0-fix-ipset-exception-on-overlap-checking-empty.patch new file mode 100644 index 0000000..3cee2c5 --- /dev/null +++ b/SOURCES/0011-v1.1.0-fix-ipset-exception-on-overlap-checking-empty.patch @@ -0,0 +1,32 @@ +From e9e1edef3af8bd1a6b7c27fdd2d580e2f1571440 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fran=C3=A7ois=20Rigault?= +Date: Sun, 28 Aug 2022 10:25:33 +0200 +Subject: [PATCH 11/17] v1.1.0: fix(ipset): exception on overlap checking empty + set + +In the case of --remove-entries-from-file, check_for_overlapping_entries +can be called with no entry in input, which fails with an exception. + +Fixes: rhbz2121985 +(cherry picked from commit 1ea554e6263ed21aa9ae6e5f0abb629d53b4a7bc) +--- + src/firewall/core/ipset.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/firewall/core/ipset.py b/src/firewall/core/ipset.py +index b160d8345669..d8e0a1ab1e56 100644 +--- a/src/firewall/core/ipset.py ++++ b/src/firewall/core/ipset.py +@@ -327,6 +327,9 @@ def check_for_overlapping_entries(entries): + # at least one entry can not be parsed + return + ++ if len(entries) == 0: ++ return ++ + # We can take advantage of some facts of IPv4Network/IPv6Network and + # how Python sorts the networks to quickly detect overlaps. + # +-- +2.39.3 + diff --git a/SOURCES/0012-v1.1.0-test-ipset-verify-remove-entries-from-file.patch b/SOURCES/0012-v1.1.0-test-ipset-verify-remove-entries-from-file.patch new file mode 100644 index 0000000..9d3122c --- /dev/null +++ b/SOURCES/0012-v1.1.0-test-ipset-verify-remove-entries-from-file.patch @@ -0,0 +1,48 @@ +From a7b4212df4e1aa05d8dcb8fd4cf5e353a84d3481 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 29 Aug 2022 08:37:50 -0400 +Subject: [PATCH 12/17] v1.1.0: test(ipset): verify --remove-entries-from-file + +Specifically if it results in an empty set. + +Coverage: rhbz2121985 +(cherry picked from commit edea40189e10d3f7777e69746592fb5e2e0e36ea) +--- + src/tests/regression/gh1011.at | 15 +++++++++++++++ + src/tests/regression/regression.at | 1 + + 2 files changed, 16 insertions(+) + create mode 100644 src/tests/regression/gh1011.at + +diff --git a/src/tests/regression/gh1011.at b/src/tests/regression/gh1011.at +new file mode 100644 +index 000000000000..037ab70648eb +--- /dev/null ++++ b/src/tests/regression/gh1011.at +@@ -0,0 +1,15 @@ ++FWD_START_TEST([remove entries results in empty]) ++AT_KEYWORDS(ipset gh1011 rhbz2121985) ++ ++FWD_CHECK([--permanent --new-ipset foobar --type hash:net], 0, [ignore]) ++AT_DATA([./empty], [dnl ++10.10.10.0/24 ++]) ++FWD_CHECK([--permanent --ipset foobar --add-entry 10.10.10.0/24], 0, [ignore]) ++FWD_CHECK([--permanent --ipset foobar --remove-entries-from-file ./empty], 0, [ignore]) ++ ++FWD_RELOAD() ++FWD_CHECK([--ipset foobar --add-entry 10.10.10.0/24], 0, [ignore]) ++FWD_CHECK([--ipset foobar --remove-entries-from-file ./empty], 0, [ignore]) ++ ++FWD_END_TEST() +diff --git a/src/tests/regression/regression.at b/src/tests/regression/regression.at +index 143298d3235f..889c66dd175d 100644 +--- a/src/tests/regression/regression.at ++++ b/src/tests/regression/regression.at +@@ -51,3 +51,4 @@ m4_include([regression/service_includes_for_builtin.at]) + m4_include([regression/rhbz2181406.at]) + m4_include([regression/ipset_scale.at]) + m4_include([regression/gh881.at]) ++m4_include([regression/gh1011.at]) +-- +2.39.3 + diff --git a/SOURCES/0013-v1.2.0-fix-ipset-fix-configuring-IP-range-for-ipsets.patch b/SOURCES/0013-v1.2.0-fix-ipset-fix-configuring-IP-range-for-ipsets.patch new file mode 100644 index 0000000..4de35a1 --- /dev/null +++ b/SOURCES/0013-v1.2.0-fix-ipset-fix-configuring-IP-range-for-ipsets.patch @@ -0,0 +1,138 @@ +From 90412a5fae831dcb1a8c9d9f4a798efabcc46567 Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Tue, 11 Jul 2023 15:26:56 +0200 +Subject: [PATCH 13/17] v1.2.0: fix(ipset): fix configuring IP range for ipsets + with nftables + +Setting an IP range with nftables did not work: + + firewall-cmd --permanent --delete-ipset=testipset || : + firewall-cmd --permanent --delete-zone=testzone || : + + ENTRY=1.1.1.1-1.1.1.10 + + firewall-cmd --permanent --new-ipset=testipset --type=hash:ip + firewall-cmd --permanent --ipset=testipset --add-entry="$ENTRY" + firewall-cmd --permanent --info-ipset=testipset + firewall-cmd --permanent --new-zone=testzone + firewall-cmd --permanent --zone=testzone --add-rich-rule='rule family="ipv4" source ipset="testipset" service name="ssh" accept' + + firewall-cmd --reload & + +This would generate the following JSON request: + + { + "add": { + "element": { + "family": "inet", + "table": "firewalld", + "name": "testipset", + "elem": [ + "1.1.1.1-1.1.1.10" + ] + } + } + } + +libnftables will try to resolve "1.1.1.1-1.1.1.10" via getaddrinfo(). Calling +getaddrinfo() to resolve names is bound to fail, and it blocks the process for +a very long time. libnftables should not block the calling process ([1]). + +We need to generate the correct JSON request, which is + + { + "add": { + "element": { + "family": "inet", + "table": "firewalld", + "name": "testipset", + "elem": [ + { + "range": [ + "1.1.1.1", + "1.1.1.10" + ] + } + ] + } + } + } + +This is an ugly fix, because the parsing of ipset entries is duplicated +and inconsistent. A better solution for that shall follow. + +[1] https://marc.info/?l=netfilter-devel&m=168901121103612 + +https://bugzilla.redhat.com/show_bug.cgi?id=2028748 + +Fixes: 1582c5dd736a ('feat: nftables: convert to libnftables JSON interface') +(cherry picked from commit 4db89e316f2d60f3cf856a7025a96a61e40b1e5a) +--- + src/firewall/core/nftables.py | 27 +++++++++++++++------------ + src/tests/cli/firewall-cmd.at | 4 ++-- + 2 files changed, 17 insertions(+), 14 deletions(-) + +diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py +index 19a649aaaa71..2764bcf93645 100644 +--- a/src/firewall/core/nftables.py ++++ b/src/firewall/core/nftables.py +@@ -1850,19 +1850,22 @@ class nftables(object): + fragment.append({"range": [port_str[:index], port_str[index+1:]]}) + + elif type_format[i] in ["ip", "net"]: +- try: +- index = entry_tokens[i].index("/") +- except ValueError: +- addr = entry_tokens[i] +- if "family" in obj.options and obj.options["family"] == "inet6": +- addr = normalizeIP6(addr) +- fragment.append(addr) ++ if '-' in entry_tokens[i]: ++ fragment.append({"range": entry_tokens[i].split('-') }) + else: +- addr = entry_tokens[i][:index] +- if "family" in obj.options and obj.options["family"] == "inet6": +- addr = normalizeIP6(addr) +- fragment.append({"prefix": {"addr": addr, +- "len": int(entry_tokens[i][index+1:])}}) ++ try: ++ index = entry_tokens[i].index("/") ++ except ValueError: ++ addr = entry_tokens[i] ++ if "family" in obj.options and obj.options["family"] == "inet6": ++ addr = normalizeIP6(addr) ++ fragment.append(addr) ++ else: ++ addr = entry_tokens[i][:index] ++ if "family" in obj.options and obj.options["family"] == "inet6": ++ addr = normalizeIP6(addr) ++ fragment.append({"prefix": {"addr": addr, ++ "len": int(entry_tokens[i][index+1:])}}) + else: + fragment.append(entry_tokens[i]) + return [{"concat": fragment}] if len(type_format) > 1 else fragment +diff --git a/src/tests/cli/firewall-cmd.at b/src/tests/cli/firewall-cmd.at +index 47bdd81f5194..c4ab3108d37c 100644 +--- a/src/tests/cli/firewall-cmd.at ++++ b/src/tests/cli/firewall-cmd.at +@@ -908,7 +908,7 @@ FWD_START_TEST([ipset]) + + dnl multi dimensional sets + FWD_CHECK([--permanent --new-ipset=foobar --type=hash:ip,port], 0, ignore) +- FWD_CHECK([--permanent --ipset=foobar --add-entry=10.10.10.10,1234], 0, ignore) ++ FWD_CHECK([--permanent --ipset=foobar --add-entry=10.10.10.10-10.10.10.12,1234], 0, ignore) + FWD_CHECK([--permanent --ipset=foobar --add-entry=10.10.10.10,2000-2100], 0, ignore) + FWD_RELOAD + NFT_LIST_SET([foobar], 0, [dnl +@@ -916,7 +916,7 @@ FWD_START_TEST([ipset]) + set foobar { + type ipv4_addr . inet_proto . inet_service + flags interval +- elements = { 10.10.10.10 . tcp . 1234, ++ elements = { 10.10.10.10-10.10.10.12 . tcp . 1234, + 10.10.10.10 . tcp . 2000-2100 } + } + } +-- +2.39.3 + diff --git a/SOURCES/0014-v1.2.0-chore-nftables-add-delete-table-helper.patch b/SOURCES/0014-v1.2.0-chore-nftables-add-delete-table-helper.patch new file mode 100644 index 0000000..5f34719 --- /dev/null +++ b/SOURCES/0014-v1.2.0-chore-nftables-add-delete-table-helper.patch @@ -0,0 +1,45 @@ +From 08f76e2aa6d7ca35cfb626f20ace1f9036cda3a0 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 14 Aug 2023 09:13:29 -0400 +Subject: [PATCH 14/17] v1.2.0: chore(nftables): add delete table helper + +This is to workaround an nftables issue where using the "delete" verb on +a table that does not exist will throw ENOENT. We can't use the newer +"destroy" verb because it's too new to rely upon. + +A simple hack is to always add the table before deleting it. The "add" +is ignored if the table already exists. + +(cherry picked from commit 8be561d26931832f000526cc41293700faa6c877) +--- + src/firewall/core/nftables.py | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py +index 2764bcf93645..1959bdce73be 100644 +--- a/src/firewall/core/nftables.py ++++ b/src/firewall/core/nftables.py +@@ -396,6 +396,20 @@ class nftables(object): + # Tables always exist in nftables + return [table] if table else IPTABLES_TO_NFT_HOOK.keys() + ++ def _build_delete_table_rules(self, table): ++ # To avoid nftables returning ENOENT we always add the table before ++ # deleting to guarantee it will exist. ++ # ++ # In the future, this add+delete should be replaced with "destroy", but ++ # that verb is too new to rely upon. ++ rules = [] ++ for family in ["inet", "ip", "ip6"]: ++ rules.append({"add": {"table": {"family": family, ++ "name": table}}}) ++ rules.append({"delete": {"table": {"family": family, ++ "name": table}}}) ++ return rules ++ + def build_flush_rules(self): + # Policy is stashed in a separate table that we're _not_ going to + # flush. As such, we retain the policy rule handles and ref counts. +-- +2.39.3 + diff --git a/SOURCES/0015-v1.2.0-fix-nftables-always-flush-main-table-on-start.patch b/SOURCES/0015-v1.2.0-fix-nftables-always-flush-main-table-on-start.patch new file mode 100644 index 0000000..9ac7b6f --- /dev/null +++ b/SOURCES/0015-v1.2.0-fix-nftables-always-flush-main-table-on-start.patch @@ -0,0 +1,38 @@ +From 0704ea3fef79cc1532f913ac1598e297016e1905 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Thu, 10 Aug 2023 08:43:03 -0400 +Subject: [PATCH 15/17] v1.2.0: fix(nftables): always flush main table on start + +On start created_tables will not contain the main "firewalld" table so a +flush command is not issued. We should always attempt to flush. If +CleanupOnExit=no, then not flushing causes duplicate rules on restart. + +Fixes: rhbz2222044 +(cherry picked from commit 6a155ea7195f2c720625e2452afa41544b4b4227) +--- + src/firewall/core/nftables.py | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py +index 1959bdce73be..e3e06d75f663 100644 +--- a/src/firewall/core/nftables.py ++++ b/src/firewall/core/nftables.py +@@ -427,13 +427,11 @@ class nftables(object): + self.policy_priority_counts = {} + self.zone_source_index_cache = {} + +- rules = [] + for family in ["inet", "ip", "ip6"]: + if TABLE_NAME in self.created_tables[family]: +- rules.append({"delete": {"table": {"family": family, +- "name": TABLE_NAME}}}) + self.created_tables[family].remove(TABLE_NAME) +- return rules ++ ++ return self._build_delete_table_rules(TABLE_NAME) + + def _build_set_policy_rules_ct_rules(self, enable): + add_del = { True: "add", False: "delete" }[enable] +-- +2.39.3 + diff --git a/SOURCES/0016-v1.2.0-test-CleanUpOnExit-verify-restart-does-not-du.patch b/SOURCES/0016-v1.2.0-test-CleanUpOnExit-verify-restart-does-not-du.patch new file mode 100644 index 0000000..5c18204 --- /dev/null +++ b/SOURCES/0016-v1.2.0-test-CleanUpOnExit-verify-restart-does-not-du.patch @@ -0,0 +1,82 @@ +From 8c79246dbc5b8945c22b313ad51be698f2b61316 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Wed, 9 Aug 2023 14:39:08 -0400 +Subject: [PATCH 16/17] v1.2.0: test(CleanUpOnExit): verify restart does not + duplicate rules + +Coverage: rhbz2222044 +(cherry picked from commit c66e752a00c05a5afa58904850d244f50528059e) +--- + src/tests/regression/regression.at | 1 + + src/tests/regression/rhbz2222044.at | 50 +++++++++++++++++++++++++++++ + 2 files changed, 51 insertions(+) + create mode 100644 src/tests/regression/rhbz2222044.at + +diff --git a/src/tests/regression/regression.at b/src/tests/regression/regression.at +index 889c66dd175d..bc9aeb1a8624 100644 +--- a/src/tests/regression/regression.at ++++ b/src/tests/regression/regression.at +@@ -52,3 +52,4 @@ m4_include([regression/rhbz2181406.at]) + m4_include([regression/ipset_scale.at]) + m4_include([regression/gh881.at]) + m4_include([regression/gh1011.at]) ++m4_include([regression/rhbz2222044.at]) +diff --git a/src/tests/regression/rhbz2222044.at b/src/tests/regression/rhbz2222044.at +new file mode 100644 +index 000000000000..9f3b1615b2f9 +--- /dev/null ++++ b/src/tests/regression/rhbz2222044.at +@@ -0,0 +1,50 @@ ++FWD_START_TEST([duplicate rules after restart]) ++AT_KEYWORDS(rhbz2222044) ++AT_SKIP_IF([! NS_CMD([command -v wc >/dev/null 2>&1])]) ++ ++dnl rules have not changed so rule count should not change ++m4_define([check_rule_count], [ ++m4_if(nftables, FIREWALL_BACKEND, [ ++NS_CHECK([nft list table inet firewalld | wc -l], 0, [dnl ++237 ++]) ++NS_CHECK([nft list table ip firewalld | wc -l], 0, [dnl ++105 ++]) ++NS_CHECK([nft list table ip6 firewalld | wc -l], 0, [dnl ++105 ++]) ++], [ dnl iptables ++NS_CHECK([iptables-save | wc -l], 0, [dnl ++256 ++]) ++])]) ++ ++dnl -------------------------- ++dnl -------------------------- ++ ++AT_CHECK([sed -i 's/^CleanupOnExit.*/CleanupOnExit=yes/' ./firewalld.conf]) ++FWD_RELOAD() ++ ++check_rule_count() ++FWD_RESTART() ++check_rule_count() ++ ++check_rule_count() ++FWD_RELOAD() ++check_rule_count() ++ ++dnl Now do it again, but with CleanupOnExit=no ++AT_CHECK([sed -i 's/^CleanupOnExit.*/CleanupOnExit=no/' ./firewalld.conf]) ++FWD_RELOAD() ++ ++check_rule_count() ++FWD_RESTART() ++check_rule_count() ++ ++check_rule_count() ++FWD_RELOAD() ++check_rule_count() ++ ++m4_undefine([check_rule_count]) ++FWD_END_TEST() +-- +2.39.3 + diff --git a/SOURCES/0017-v1.2.0-chore-nftables-policy-use-delete-table-helper.patch b/SOURCES/0017-v1.2.0-chore-nftables-policy-use-delete-table-helper.patch new file mode 100644 index 0000000..8bb305d --- /dev/null +++ b/SOURCES/0017-v1.2.0-chore-nftables-policy-use-delete-table-helper.patch @@ -0,0 +1,32 @@ +From 2ca79f8ebbadcf39f9b378b7fd296fcef13a4c54 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 14 Aug 2023 09:21:17 -0400 +Subject: [PATCH 17/17] v1.2.0: chore(nftables): policy: use delete table + helper + +Use the new table delete helper when deleting the policy table. + +(cherry picked from commit a291a5d2f03711c2c6b0079128626204229ad79e) +--- + src/firewall/core/nftables.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py +index e3e06d75f663..2a13b2678a94 100644 +--- a/src/firewall/core/nftables.py ++++ b/src/firewall/core/nftables.py +@@ -489,9 +489,9 @@ class nftables(object): + if policy_key in self.rule_to_handle: + rules.append(rule) + ++ rules += self._build_delete_table_rules(TABLE_NAME_POLICY) ++ + if TABLE_NAME_POLICY in self.created_tables["inet"]: +- rules.append({"delete": {"table": {"family": "inet", +- "name": TABLE_NAME_POLICY}}}) + self.created_tables["inet"].remove(TABLE_NAME_POLICY) + else: + FirewallError(UNKNOWN_ERROR, "not implemented") +-- +2.39.3 + diff --git a/SPECS/firewalld.spec b/SPECS/firewalld.spec index 5068d9e..c49fce7 100644 --- a/SPECS/firewalld.spec +++ b/SPECS/firewalld.spec @@ -1,7 +1,7 @@ Summary: A firewall daemon with D-Bus interface providing a dynamic firewall Name: firewalld Version: 0.9.11 -Release: 1%{?dist} +Release: 4%{?dist} URL: http://www.firewalld.org License: GPLv2+ Source0: https://github.com/firewalld/firewalld/releases/download/v%{version}/firewalld-%{version}.tar.gz @@ -15,6 +15,13 @@ Patch7: 0007-RHEL-only-default-to-CleanupModulesOnExit-yes.patch Patch8: 0008-v1.1.0-fix-ipset-reduce-cost-of-entry-overlap-detect.patch Patch9: 0009-v1.1.0-test-ipset-huge-set-of-entries-benchmark.patch Patch10: 0010-v1.1.0-fix-ipset-further-reduce-cost-of-entry-overla.patch +Patch11: 0011-v1.1.0-fix-ipset-exception-on-overlap-checking-empty.patch +Patch12: 0012-v1.1.0-test-ipset-verify-remove-entries-from-file.patch +Patch13: 0013-v1.2.0-fix-ipset-fix-configuring-IP-range-for-ipsets.patch +Patch14: 0014-v1.2.0-chore-nftables-add-delete-table-helper.patch +Patch15: 0015-v1.2.0-fix-nftables-always-flush-main-table-on-start.patch +Patch16: 0016-v1.2.0-test-CleanUpOnExit-verify-restart-does-not-du.patch +Patch18: 0017-v1.2.0-chore-nftables-policy-use-delete-table-helper.patch BuildArch: noarch BuildRequires: autoconf @@ -216,6 +223,15 @@ desktop-file-install --delete-original \ %{_mandir}/man1/firewall-config*.1* %changelog +* Fri Nov 03 2023 Eric Garver - 0.9.11-4 +- fix(nftables): always flush main table on start + +* Fri Nov 03 2023 Eric Garver - 0.9.11-3 +- fix(ipset): fix configuring IP range for ipsets with nftables + +* Fri Nov 03 2023 Eric Garver - 0.9.11-2 +- fix(ipset): exception on overlap checking empty set + * Tue Apr 18 2023 Eric Garver - 0.9.11-1 - rebase to v0.9.11