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