From 12eefb56e9dbbaa8d33a8c96855085a1ea7f9751 Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Mar 27 2020 14:36:03 +0000 Subject: [PATCH 1/4] Do not refer to hardcoded selinux-policy rpm in signature Get package name and version from package which owns /etc/selinux/SELINUXTYPE Fixes: https://pagure.io/setroubleshoot/issue/7 --- diff --git a/framework/src/setroubleshoot/signature.py b/framework/src/setroubleshoot/signature.py index bcc3740..6fa5ac0 100755 --- a/framework/src/setroubleshoot/signature.py +++ b/framework/src/setroubleshoot/signature.py @@ -141,7 +141,7 @@ class SEEnvironment(XmlSerialize): self.platform, self.kernel = get_os_environment() self.policy_type = selinux.selinux_getpolicytype()[1] - self.policy_rpm = get_rpm_nvr_by_name("selinux-policy") + self.policy_rpm = get_rpm_nvr_by_file_path("/etc/selinux/%s" % self.policy_type) self.local_policy_rpm = self.policy_rpm self.policyvers = str(selinux.security_policyvers()) enforce = selinux.security_getenforce() From 1b5f51898e7bfdbb80e938fe968a46eced43cbb9 Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Mar 27 2020 14:36:03 +0000 Subject: [PATCH 2/4] framework: Add dpkg support Detect whether there's `rpm` or `dpkg` available and use it for package queries. Resolves: https://pagure.io/setroubleshoot/issue/6 --- diff --git a/framework/src/setroubleshoot/audit_data.py b/framework/src/setroubleshoot/audit_data.py index d66e757..a4fc3f6 100644 --- a/framework/src/setroubleshoot/audit_data.py +++ b/framework/src/setroubleshoot/audit_data.py @@ -1025,12 +1025,12 @@ class AVC: def derive_environmental_info(self): if self.query_environment: if self.spath: - self.source_pkg = get_rpm_nvr_by_file_path(self.spath) + self.source_pkg = get_package_nvr_by_file_path(self.spath) if self.source_pkg: self.src_rpms.append(self.source_pkg) if self.tpath: - rpm = get_rpm_nvr_by_file_path(self.tpath) + rpm = get_package_nvr_by_file_path(self.tpath) if rpm: self.tgt_rpms.append(rpm) diff --git a/framework/src/setroubleshoot/browser.py b/framework/src/setroubleshoot/browser.py index 9bbd07b..4870590 100644 --- a/framework/src/setroubleshoot/browser.py +++ b/framework/src/setroubleshoot/browser.py @@ -121,7 +121,7 @@ def old(): desktop_icon_dict = {} for desktop_app_info in Gio.app_info_get_all(): exe = fullpath(desktop_app_info.get_executable()) - rpmver = get_rpm_nvr_by_file_path(exe) + rpmver = get_package_nvr_by_file_path(exe) if rpmver: if rpmver in desktop_icon_dict: desktop_icon_dict[rpmver].append(desktop_app_info) @@ -144,7 +144,7 @@ def get_icon(path, tclass="*"): if icon: return icon - rpmver = get_rpm_nvr_by_file_path(path) + rpmver = get_package_nvr_by_file_path(path) if rpmver in desktop_icon_dict: for m in desktop_icon_dict[rpmver]: icon = m.get_icon() diff --git a/framework/src/setroubleshoot/signature.py b/framework/src/setroubleshoot/signature.py index 6fa5ac0..a3f4f1c 100755 --- a/framework/src/setroubleshoot/signature.py +++ b/framework/src/setroubleshoot/signature.py @@ -141,7 +141,7 @@ class SEEnvironment(XmlSerialize): self.platform, self.kernel = get_os_environment() self.policy_type = selinux.selinux_getpolicytype()[1] - self.policy_rpm = get_rpm_nvr_by_file_path("/etc/selinux/%s" % self.policy_type) + self.policy_rpm = get_package_nvr_by_file_path("/etc/selinux/%s" % self.policy_type) self.local_policy_rpm = self.policy_rpm self.policyvers = str(selinux.security_policyvers()) enforce = selinux.security_getenforce() diff --git a/framework/src/setroubleshoot/util.py b/framework/src/setroubleshoot/util.py index 4d18555..e537bbe 100755 --- a/framework/src/setroubleshoot/util.py +++ b/framework/src/setroubleshoot/util.py @@ -33,8 +33,8 @@ __all__ = [ 'default_date_text', 'get_standard_directories', 'get_rpm_nvr_from_header', - 'get_rpm_nvr_by_name', - 'get_rpm_nvr_by_file_path', + 'get_package_nvr_by_name', + 'get_package_nvr_by_file_path', 'get_rpm_nvr_by_type', 'get_rpm_nvr_by_scontext', 'get_rpm_source_package', @@ -63,6 +63,7 @@ __all__ = [ 'TimeStamp', 'Retry', + 'PACKAGE_MANAGER', ] import bz2 @@ -74,7 +75,9 @@ from gi.repository import GObject import os import pwd import re +import shutil import selinux +import subprocess import sys import textwrap import time @@ -98,6 +101,12 @@ def is_type(obj): DATABASE_MAJOR_VERSION = 3 DATABASE_MINOR_VERSION = 0 +PACKAGE_MANAGER = None +if shutil.which('rpm'): + PACKAGE_MANAGER = 'rpm' +elif shutil.which('dpkg'): + PACKAGE_MANAGER = 'deb' + redhat_release_path = '/etc/redhat-release' text_wrapper = textwrap.TextWrapper() fix_newline_re = re.compile(r"\s*\n+\s*") @@ -305,15 +314,19 @@ def default_date_text(date): def get_standard_directories(): + """ +>>> get_standard_directories() +[...'/bin'...] + """ lst = [] - import rpm try: - ts = rpm.ts() - h = next(ts.dbMatch("name", "filesystem")) - for i in h.fiFromHeader(): - lst.append(i[0]) + if PACKAGE_MANAGER == "rpm": + lst = subprocess.check_output(["rpm", "-ql", "filesystem"], universal_newlines=True).rstrip().split("\n") + if PACKAGE_MANAGER == "deb": + lst = subprocess.check_output(["dpkg", "-L", "base-files"], universal_newlines=True).rstrip().split("\n") + except: - syslog.syslog(syslog.LOG_ERR, "failed to get filesystem list from rpm") + syslog.syslog(syslog.LOG_ERR, "failed to get list from {}".format(PACKAGE_MANAGER)) return lst @@ -326,23 +339,33 @@ def get_rpm_nvr_from_header(hdr): return "%s-%s-%s" % (name, version, release) -### these functions are for now until rpm memory leak gets a fix - - -def get_rpm_nvr_by_name_temporary(name): +def get_package_nvr_by_name(name): + """ +>>> get_package_nvr_by_name("coreutils") +'coreutils-8.30-3+b1:amd64' + """ if name is None: return None nvr = None try: - import subprocess - nvr = subprocess.check_output(["rpm", "-q", name], universal_newlines=True).rstrip() + if PACKAGE_MANAGER == 'rpm': + nvr = subprocess.check_output(["rpm", "-q", name], universal_newlines=True).rstrip() + if PACKAGE_MANAGER == 'deb': + # dpkg-query -f='${Package}_${Version}:${Architecture}\n' -W + nvr = subprocess.check_output( + ["dpkg-query", "-f=${Package}-${Version}:${Architecture}", "-W", name], universal_newlines=True + ).rstrip() except: syslog.syslog(syslog.LOG_ERR, "failed to retrieve rpm info for %s" % name) return nvr -def get_rpm_nvr_by_file_path_temporary(name): +def get_package_nvr_by_file_path(name): + """ +>>> get_package_nvr_by_file_path("/bin/ls") +'coreutils-8.30-3+b1:amd64' + """ if name is None: return None @@ -352,8 +375,16 @@ def get_rpm_nvr_by_file_path_temporary(name): nvr = None try: - import subprocess - nvr = subprocess.check_output(["rpm", "-qf", name], universal_newlines=True).rstrip() + if PACKAGE_MANAGER == 'rpm': + nvr = subprocess.check_output(["rpm", "-qf", name], universal_newlines=True).rstrip() + if PACKAGE_MANAGER == 'deb': + # dpkg -S foo |cut -d: -1f + # dpkg-query -f='${Package}_${Version}:${Architecture}\n' -W + package_name = subprocess.check_output(["dpkg", "-S", name]).decode().split(": ")[0] + nvr = subprocess.check_output( + ["dpkg-query", "-f=${Package}-${Version}:${Architecture}", "-W", package_name], universal_newlines=True + ).rstrip() + except: syslog.syslog(syslog.LOG_ERR, "failed to retrieve rpm info for %s" % name) return nvr @@ -367,42 +398,6 @@ except ValueError: file_types = [] -def get_rpm_nvr_by_name(name): - return get_rpm_nvr_by_name_temporary(name) - if name is None: - return None - - import rpm - nvr = None - try: - ts = rpm.ts() - mi = ts.dbMatch(rpm.RPMTAG_NAME, name) - for h in mi: - nvr = get_rpm_nvr_from_header(h) - break - except: - syslog.syslog(syslog.LOG_ERR, "failed to retrieve rpm info for %s" % name) - return nvr - - -def get_rpm_nvr_by_file_path(path): - return get_rpm_nvr_by_file_path_temporary(path) - if path is None: - return None - - import rpm - nvr = None - try: - ts = rpm.ts() - mi = ts.dbMatch(rpm.RPMTAG_BASENAMES, path) - for h in mi: - nvr = get_rpm_nvr_from_header(h) - break - except: - syslog.syslog(syslog.LOG_ERR, "failed to retrieve rpm info for %s" % path) - return nvr - - def split_rpm_nvr(nvr): components = nvr.split('-') release = components[-1] @@ -455,7 +450,7 @@ Finds an SELinux module which defines given SELinux type pass if len(modules) > 0: - return get_rpm_nvr_by_file_path(sorted(modules)[-1]) + return get_package_nvr_by_file_path(sorted(modules)[-1]) return None From 1de3fd53785b0dca6bf3dc2c4d8f8005a597b232 Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Mar 27 2020 14:36:03 +0000 Subject: [PATCH 3/4] plugins: Use get_package_nvr* functions instead of get_rpm_nvr* Resolves: https://pagure.io/setroubleshoot/issue/6 --- diff --git a/plugins/src/mozplugger.py b/plugins/src/mozplugger.py index b5705df..01f72d1 100644 --- a/plugins/src/mozplugger.py +++ b/plugins/src/mozplugger.py @@ -52,9 +52,9 @@ Either remove the mozplugger or spice-xpi package by executing 'yum remove mozpl def analyze(self, avc): if avc.matches_source_types(['mozilla_plugin_t']): reports = [] - if get_rpm_nvr_by_name("mozplugger"): + if get_package_nvr_by_name("mozplugger"): reports.append(self.report(("mozplugger", None))) - if get_rpm_nvr_by_name("spice-xpi"): + if get_package_nvr_by_name("spice-xpi"): reports.append(self.report(("spice-xpi", None))) if len(reports) > 0: return reports diff --git a/plugins/src/mozplugger_remove.py b/plugins/src/mozplugger_remove.py index d44c339..d6b514a 100644 --- a/plugins/src/mozplugger_remove.py +++ b/plugins/src/mozplugger_remove.py @@ -53,7 +53,7 @@ setsebool -P unconfined_mozilla_plugin_transition 0 def analyze(self, avc): if (avc.matches_source_types(['mozilla_plugin_t']) and - get_rpm_nvr_by_name("mozplugger")): + get_package_nvr_by_name("mozplugger")): # MATCH return self.report() else: From 7458f4c50ac07319b0aa1b766547137bb7e7d391 Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Mar 27 2020 14:36:03 +0000 Subject: [PATCH 4/4] setroubleshoot.util: Catch exceptions from sepolicy import Fixes the following bt on SELinux disable system: File "src/setroubleshoot/util.py", line 370, in file_types = get_all_file_types() File "/usr/lib/python3/dist-packages/sepolicy/__init__.py", line 960, in get_all_file_types file_types = list(sorted(info(ATTRIBUTE, "file_type"))[0]["types"]) File "/usr/lib/python3/dist-packages/sepolicy/__init__.py", line 224, in return ({ File "/usr/lib/python3/dist-packages/setools/typeattrquery.py", line 65, in results for attr in self.policy.typeattributes(): --- diff --git a/framework/src/setroubleshoot/util.py b/framework/src/setroubleshoot/util.py index e537bbe..023d1c4 100755 --- a/framework/src/setroubleshoot/util.py +++ b/framework/src/setroubleshoot/util.py @@ -390,11 +390,10 @@ def get_package_nvr_by_file_path(name): return nvr ### - -from sepolicy import get_all_file_types try: + from sepolicy import get_all_file_types file_types = get_all_file_types() -except ValueError: +except: file_types = []