From 5c873d88bceaf3bbaf2d781a812cbc4415c8b26a Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Wed, 30 Oct 2019 08:24:46 -0400
Subject: [PATCH 115/122] fix: failure to load modules no longer fatal
There are many cases in which module loading may fail:
- builtin modules, but corrupt/missing modules.builtin database
- CONFIG_MODULES=n
- inside unprivileged container
Unfortunately, we have no way to detect these scenarios. The only thing
we can do is attempt to load the module and hope for the best.
Fixes: #430
Fixes: #519
(cherry picked from commit 88e76ddfed6fe348975bfea9002da0e4627c6e25)
(cherry picked from commit 407af3a6d2f5f0ca6e8a354a8cbfdb3228ad04bf)
---
src/firewall/core/fw.py | 17 +++++++++--------
src/firewall/core/fw_transaction.py | 13 ++++++++-----
src/tests/functions.at | 1 +
3 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/src/firewall/core/fw.py b/src/firewall/core/fw.py
index 3e639f83d1f4..2c4325966a19 100644
--- a/src/firewall/core/fw.py
+++ b/src/firewall/core/fw.py
@@ -385,10 +385,9 @@ class Firewall(object):
#
# NOTE: must force loading of nf_conntrack to make sure the values are
# available in /proc
- module_return = self.handle_modules(["nf_conntrack"], True)
- if module_return:
- log.error("Failed to load nf_conntrack module: %s" % module_return[1])
- sys.exit(1)
+ (status, msg) = self.handle_modules(["nf_conntrack"], True)
+ if status != 0:
+ log.warning("Failed to load nf_conntrack module: %s" % msg)
if self._automatic_helpers != "system":
functions.set_nf_conntrack_helper_setting(self._automatic_helpers == "yes")
self.nf_conntrack_helper_setting = \
@@ -664,6 +663,8 @@ class Firewall(object):
# handle modules
def handle_modules(self, _modules, enable):
+ num_failed = 0
+ error_msgs = ""
for i,module in enumerate(_modules):
if enable:
(status, msg) = self.modules_backend.load_module(module)
@@ -673,9 +674,9 @@ class Firewall(object):
else:
(status, msg) = self.modules_backend.unload_module(module)
if status != 0:
- if enable:
- return (_modules[:i], msg) # cleanup modules and error msg
- # else: ignore cleanup
+ num_failed += 1
+ error_msgs += msg
+ continue
if enable:
self._module_refcount.setdefault(module, 0)
@@ -685,7 +686,7 @@ class Firewall(object):
self._module_refcount[module] -= 1
if self._module_refcount[module] == 0:
del self._module_refcount[module]
- return None
+ return (num_failed, error_msgs)
def _select_firewall_backend(self, backend):
if backend != "nftables":
diff --git a/src/firewall/core/fw_transaction.py b/src/firewall/core/fw_transaction.py
index ad204c1991cf..d5d3e858b6dd 100644
--- a/src/firewall/core/fw_transaction.py
+++ b/src/firewall/core/fw_transaction.py
@@ -113,11 +113,14 @@ class SimpleFirewallTransaction(object):
if not error:
module_return = self.fw.handle_modules(modules, enable)
if module_return:
- (cleanup_modules, msg) = module_return
- if cleanup_modules is not None:
- error = True
- errorMsg = msg
- self.fw.handle_modules(cleanup_modules, not enable)
+ # Debug log about issues loading modules, but don't error. The
+ # modules may be builtin or CONFIG_MODULES=n, in which case
+ # modprobe will fail. Or we may be running inside a container
+ # that doesn't have sufficient privileges. Unfortunately there
+ # is no way for us to know.
+ (status, msg) = module_return
+ if status:
+ log.debug1(msg)
# error case: revert rules
if error:
diff --git a/src/tests/functions.at b/src/tests/functions.at
index 209f0f5d2ea9..17ca6c9fc052 100644
--- a/src/tests/functions.at
+++ b/src/tests/functions.at
@@ -143,6 +143,7 @@ m4_define([FWD_END_TEST], [
IF_IPV6_SUPPORTED([], [
sed -i "/WARNING: ip6tables not usable, disabling IPv6 firewall/d" ./firewalld.log
])
+ sed -i "/modprobe: ERROR:/d" ./firewalld.log
if test x"$1" != x"ignore"; then
if test -n "$1"; then
sed -i $1 ./firewalld.log
--
2.23.0