Blob Blame History Raw
From 8c2a4bc33d0c60a9fb84f01f360c524c9f725e03 Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Thu, 24 Oct 2019 12:47:36 -0400
Subject: [PATCH 116/122] fix: don't probe for available kernel modules

Trust what's specified by the helper definitions. This also completely
removes our dependency on modinfo. modinfo becomes very problematic if
the kernel modules are builtin.

Fixes: #517
Closes: #518
(cherry picked from commit adbf3476b7533ef3a2c002db62f76614a9f0f6c1)
(cherry picked from commit 7065561488166bbcb16cf8b9e8a2731b0c0379d8)
---
 configure.ac                       |  1 -
 src/firewall/config/__init__.py.in |  1 -
 src/firewall/core/fw.py            | 24 -----------
 src/firewall/core/fw_zone.py       | 40 +++++-------------
 src/firewall/functions.py          | 66 +-----------------------------
 src/firewall/server/firewalld.py   |  4 +-
 6 files changed, 15 insertions(+), 121 deletions(-)

diff --git a/configure.ac b/configure.ac
index d1c365e29986..1f8f8dff07ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,7 +30,6 @@ AM_PATH_PYTHON
 AC_PATH_PROG([XSLTPROC], [xsltproc])
 AC_PATH_PROG([KILL], [kill], [/usr/bin/kill])
 
-AC_PATH_PROG([MODINFO], [modinfo], [/sbin/modinfo])
 AC_PATH_PROG([MODPROBE], [modprobe], [/sbin/modprobe])
 AC_PATH_PROG([RMMOD], [rmmod], [/sbin/rmmod])
 AC_PATH_PROG([SYSCTL], [sysctl], [/sbin/sysctl])
diff --git a/src/firewall/config/__init__.py.in b/src/firewall/config/__init__.py.in
index 20e4979062d8..1b2168bde44d 100644
--- a/src/firewall/config/__init__.py.in
+++ b/src/firewall/config/__init__.py.in
@@ -110,7 +110,6 @@ COMMANDS = {
     "eb":           "@EBTABLES@",
     "eb-restore":   "@EBTABLES_RESTORE@",
     "ipset":        "@IPSET@",
-    "modinfo":      "@MODINFO@",
     "modprobe":     "@MODPROBE@",
     "rmmod":        "@RMMOD@",
     "nft":          "@NFT@",
diff --git a/src/firewall/core/fw.py b/src/firewall/core/fw.py
index 2c4325966a19..b1643a1ebff4 100644
--- a/src/firewall/core/fw.py
+++ b/src/firewall/core/fw.py
@@ -114,8 +114,6 @@ class Firewall(object):
         self._automatic_helpers = config.FALLBACK_AUTOMATIC_HELPERS
         self._firewall_backend = config.FALLBACK_FIREWALL_BACKEND
         self.nf_conntrack_helper_setting = 0
-        self.nf_conntrack_helpers = { }
-        self.nf_nat_helpers = { }
 
     def individual_calls(self):
         return self._individual_calls
@@ -198,28 +196,6 @@ class Firewall(object):
             log.debug1("ebtables-restore is not supporting the --noflush "
                        "option, will therefore not be used")
 
-        if os.path.exists(config.COMMANDS["modinfo"]):
-            self.nf_conntrack_helpers = functions.get_nf_conntrack_helpers()
-            if len(self.nf_conntrack_helpers) > 0:
-                log.debug1("Conntrack helpers supported by the kernel:")
-                for key,values in self.nf_conntrack_helpers.items():
-                    log.debug1("  %s: %s", key, ", ".join(values))
-            else:
-                log.debug1("No conntrack helpers supported by the kernel.")
-
-            self.nf_nat_helpers = functions.get_nf_nat_helpers()
-            if len(self.nf_nat_helpers) > 0:
-                log.debug1("NAT helpers supported by the kernel:")
-                for key,values in self.nf_nat_helpers.items():
-                    log.debug1("  %s: %s", key, ", ".join(values))
-            else:
-                log.debug1("No NAT helpers supported by the kernel.")
-
-        else:
-            self.nf_conntrack_helpers = { }
-            self.nf_nat_helpers = { }
-            log.warning("modinfo command is missing, not able to detect conntrack helpers.")
-
     def _start(self, reload=False, complete_reload=False):
         # initialize firewall
         default_zone = config.FALLBACK_ZONE
diff --git a/src/firewall/core/fw_zone.py b/src/firewall/core/fw_zone.py
index e7be779ebc8c..b1dcce240063 100644
--- a/src/firewall/core/fw_zone.py
+++ b/src/firewall/core/fw_zone.py
@@ -846,20 +846,16 @@ class FirewallZone(object):
                 helper = self._fw.helper.get_helper(module)
             except FirewallError:
                 raise FirewallError(errors.INVALID_HELPER, module)
-            if helper.module not in self._fw.nf_conntrack_helpers:
-                raise FirewallError(
-                    errors.INVALID_HELPER,
-                    "'%s' is not available" % helper.module)
             if self._fw.nf_conntrack_helper_setting == 0 and \
                len(helper.ports) < 1:
-                for mod in self._fw.nf_conntrack_helpers[helper.module]:
-                    try:
-                        _helper = self._fw.helper.get_helper(mod)
-                    except FirewallError:
-                        if enable:
-                            log.warning("Helper '%s' is not available" % mod)
-                        continue
+                _module_short_name = get_nf_conntrack_short_name(helper.module)
+                try:
+                    _helper = self._fw.helper.get_helper(_module_short_name)
                     _helpers.append(_helper)
+                except FirewallError:
+                    if enable:
+                        log.warning("Helper '%s' is not available" % _module_short_name)
+                    continue
             else:
                 _helpers.append(helper)
         return _helpers
@@ -1611,14 +1607,8 @@ class FirewallZone(object):
                             module = helper.module
                             _module_short_name = get_nf_conntrack_short_name(module)
                             if self._fw.nf_conntrack_helper_setting == 0:
-                                if _module_short_name not in \
-                                   self._fw.nf_conntrack_helpers[module]:
-                                    raise FirewallError(
-                                        errors.INVALID_HELPER,
-                                        "'%s' not available in kernel" % module)
                                 nat_module = module.replace("conntrack", "nat")
-                                if nat_module in self._fw.nf_nat_helpers:
-                                    modules.append(nat_module)
+                                modules.append(nat_module)
                                 if helper.family != "" and not backend.is_ipv_supported(helper.family):
                                     # no support for family ipv, continue
                                     continue
@@ -1634,8 +1624,7 @@ class FirewallZone(object):
                                 if helper.module not in modules:
                                     modules.append(helper.module)
                                     nat_module = helper.module.replace("conntrack", "nat")
-                                    if nat_module in self._fw.nf_nat_helpers:
-                                        modules.append(nat_module)
+                                    modules.append(nat_module)
                         zone_transaction.add_modules(modules)
 
                     # create rules
@@ -1796,8 +1785,7 @@ class FirewallZone(object):
                 for helper in helpers:
                     modules.append(helper.module)
                     nat_module = helper.module.replace("conntrack", "nat")
-                    if nat_module in self._fw.nf_nat_helpers:
-                        modules.append(nat_module)
+                    modules.append(nat_module)
                 zone_transaction.add_modules(modules)
             zone_transaction.add_chain("filter", "INPUT")
 
@@ -1821,14 +1809,8 @@ class FirewallZone(object):
                 for helper in helpers:
                     module = helper.module
                     _module_short_name = get_nf_conntrack_short_name(module)
-                    if _module_short_name not in \
-                       self._fw.nf_conntrack_helpers[module]:
-                        raise FirewallError(
-                            errors.INVALID_HELPER,
-                            "'%s' is not available in kernel" % module)
                     nat_module = helper.module.replace("conntrack", "nat")
-                    if nat_module in self._fw.nf_nat_helpers:
-                        zone_transaction.add_module(nat_module)
+                    zone_transaction.add_module(nat_module)
                     if helper.family != "" and not backend.is_ipv_supported(helper.family):
                         # no support for family ipv, continue
                         continue
diff --git a/src/firewall/functions.py b/src/firewall/functions.py
index ad2166905d1d..8793ac3dbf21 100644
--- a/src/firewall/functions.py
+++ b/src/firewall/functions.py
@@ -24,8 +24,7 @@ __all__ = [ "PY2", "getPortID", "getPortRange", "portStr", "getServiceName",
             "checkProtocol", "checkInterface", "checkUINT32",
             "firewalld_is_active", "tempFile", "readfile", "writefile",
             "enable_ip_forwarding", "get_nf_conntrack_helper_setting",
-            "set_nf_conntrack_helper_setting", "get_nf_conntrack_helpers",
-            "get_nf_nat_helpers", "check_port", "check_address",
+            "set_nf_conntrack_helper_setting", "check_port", "check_address",
             "check_single_address", "check_mac", "uniqify", "ppid_of_pid",
             "max_zone_name_len", "checkUser", "checkUid", "checkCommand",
             "checkContext", "joinArgs", "splitArgs",
@@ -40,8 +39,7 @@ import string
 import sys
 import tempfile
 from firewall.core.logger import log
-from firewall.core.prog import runProg
-from firewall.config import FIREWALLD_TEMPDIR, FIREWALLD_PIDFILE, COMMANDS
+from firewall.config import FIREWALLD_TEMPDIR, FIREWALLD_PIDFILE
 
 PY2 = sys.version < '3'
 
@@ -348,66 +346,6 @@ def enable_ip_forwarding(ipv):
 def get_nf_conntrack_short_name(module):
     return module.replace("_","-").replace("nf-conntrack-", "")
 
-def get_nf_conntrack_helpers():
-    kver = os.uname()[2]
-    path = "/lib/modules/%s/kernel/net/netfilter/" % kver
-    helpers = { }
-    if os.path.isdir(path):
-        for filename in sorted(os.listdir(path)):
-            if not filename.startswith("nf_conntrack_"):
-                continue
-            module = filename.split(".")[0]
-            (status, ret) = runProg(COMMANDS["modinfo"], [ module, ])
-            if status != 0:
-                continue
-            # If module name matches "nf_conntrack_proto_*"
-            # the we add it to helpers list and goto next module
-            if filename.startswith("nf_conntrack_proto_"):
-                helper = filename.split(".")[0].strip()
-                helper = get_nf_conntrack_short_name(helper)
-                helpers.setdefault(module, [ ]).append(helper)
-                continue
-            # Else we get module alias and if "-helper" in the "alias:" line of modinfo
-            # then we add it to helpers list and goto next module
-            for line in ret.split("\n"):
-                if line.startswith("alias:") and "-helper-" in line:
-                    helper = line.split(":")[1].strip()
-                    helper = helper.replace("nfct-helper-", "")
-                    helper = helper.replace("_", "-")
-                    helpers.setdefault(module, [ ]).append(helper)
-    return helpers
-
-def get_nf_nat_helpers():
-    kver = os.uname()[2]
-    helpers = { }
-    for path in ["/lib/modules/%s/kernel/net/netfilter/" % kver,
-                 "/lib/modules/%s/kernel/net/ipv4/netfilter/" % kver,
-                 "/lib/modules/%s/kernel/net/ipv6/netfilter/" % kver]:
-        if os.path.isdir(path):
-            for filename in sorted(os.listdir(path)):
-                if not filename.startswith("nf_nat_"):
-                    continue
-                module = filename.split(".")[0]
-                (status, ret) = runProg(COMMANDS["modinfo"], [ module, ])
-                if status != 0:
-                    continue
-                # If module name matches "nf_nat_proto_*"
-                # the we add it to helpers list and goto next module
-                if filename.startswith("nf_nat_proto_"):
-                    helper = filename.split(".")[0].strip()
-                    helper = helper.replace("_", "-")
-                    helper = helper.replace("nf-nat-", "")
-                    helpers.setdefault(module, [ ]).append(helper)
-                    continue
-                # Else we get module alias and if "NAT helper" in "description:" line of modinfo
-                # then we add it to helpers list and goto next module
-                for line in ret.split("\n"):
-                    if line.startswith("description:") and "NAT helper" in line:
-                        helper = module.replace("nf_nat_", "")
-                        helper = helper.replace("_", "-")
-                        helpers.setdefault(module, [ ]).append(helper)
-    return helpers
-
 def get_nf_conntrack_helper_setting():
     try:
         return int(readfile("/proc/sys/net/netfilter/nf_conntrack_helper")[0])
diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py
index bc04f2d0f4c3..265c58bc3dcc 100644
--- a/src/firewall/server/firewalld.py
+++ b/src/firewall/server/firewalld.py
@@ -186,10 +186,10 @@ class FirewallD(slip.dbus.service.Object):
             return dbus.Boolean(self.fw.nf_conntrack_helper_setting == 1)
 
         elif prop == "nf_conntrack_helpers":
-            return dbus.Dictionary(self.fw.nf_conntrack_helpers, "sas")
+            return dbus.Dictionary({}, "sas")
 
         elif prop == "nf_nat_helpers":
-            return dbus.Dictionary(self.fw.nf_nat_helpers, "sas")
+            return dbus.Dictionary({}, "sas")
 
         else:
             raise dbus.exceptions.DBusException(
-- 
2.23.0