From 654cae43b73d0f01d0d2c04f227511efe8d93e4c Mon Sep 17 00:00:00 2001 From: MSVSphere Packaging Team Date: Wed, 3 Jul 2024 03:18:02 +0300 Subject: [PATCH] import policycoreutils-2.9-26.el8_10 --- ...den-more-tools-against-rogue-modules.patch | 98 +++++ ...054-sepolicy-port-to-dnf4-python-API.patch | 95 +++++ ...Do-not-sort-local-fcontext-definitio.patch | 64 +++ ...anage-Allow-modifying-records-on-add.patch | 396 ++++++++++++++++++ SPECS/policycoreutils.spec | 14 +- 5 files changed, 666 insertions(+), 1 deletion(-) create mode 100644 SOURCES/0053-python-Harden-more-tools-against-rogue-modules.patch create mode 100644 SOURCES/0054-sepolicy-port-to-dnf4-python-API.patch create mode 100644 SOURCES/0055-python-semanage-Do-not-sort-local-fcontext-definitio.patch create mode 100644 SOURCES/0056-python-semanage-Allow-modifying-records-on-add.patch diff --git a/SOURCES/0053-python-Harden-more-tools-against-rogue-modules.patch b/SOURCES/0053-python-Harden-more-tools-against-rogue-modules.patch new file mode 100644 index 0000000..06db59d --- /dev/null +++ b/SOURCES/0053-python-Harden-more-tools-against-rogue-modules.patch @@ -0,0 +1,98 @@ +From 7aef364bc6607953a34cb9e8fe9ea51c88379a5c Mon Sep 17 00:00:00 2001 +From: Vit Mojzis +Date: Wed, 6 Dec 2023 15:31:51 +0100 +Subject: [PATCH] python: Harden more tools against "rogue" modules + +Python scripts present in the same directory as the tool +override regular modules. + +Fixes: + #cat > /usr/bin/signal.py < +Acked-by: James Carter +--- + dbus/selinux_server.py | 2 +- + gui/polgengui.py | 2 +- + gui/system-config-selinux.py | 6 +++--- + sandbox/sandbox | 2 +- + sandbox/start | 2 +- + 5 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/dbus/selinux_server.py b/dbus/selinux_server.py +index 97bf91ba..eae38de5 100644 +--- a/dbus/selinux_server.py ++++ b/dbus/selinux_server.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python3 ++#!/usr/bin/python3 -EsI + + import dbus + import dbus.service +diff --git a/gui/polgengui.py b/gui/polgengui.py +index 46a1bd2c..0402e82c 100644 +--- a/gui/polgengui.py ++++ b/gui/polgengui.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python3 -Es ++#!/usr/bin/python3 -EsI + # + # polgengui.py - GUI for SELinux Config tool in system-config-selinux + # +diff --git a/gui/system-config-selinux.py b/gui/system-config-selinux.py +index 1e0d5eb1..c344c076 100644 +--- a/gui/system-config-selinux.py ++++ b/gui/system-config-selinux.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/python3 -Es ++#!/usr/bin/python3 -EsI + # + # system-config-selinux.py - GUI for SELinux Config tool in system-config-selinux + # +@@ -32,6 +32,8 @@ except RuntimeError as e: + print("This is a graphical application and requires DISPLAY to be set.") + sys.exit(1) + ++sys.path.append('/usr/share/system-config-selinux') ++ + from gi.repository import GObject + import statusPage + import booleansPage +@@ -65,8 +67,6 @@ except: + + version = "1.0" + +-sys.path.append('/usr/share/system-config-selinux') +- + + ## + ## Pull in the Glade file +diff --git a/sandbox/sandbox b/sandbox/sandbox +index 707959a6..e276e594 100644 +--- a/sandbox/sandbox ++++ b/sandbox/sandbox +@@ -1,4 +1,4 @@ +-#!/usr/bin/python3 -Es ++#!/usr/bin/python3 -EsI + # Authors: Dan Walsh + # Authors: Thomas Liu + # Authors: Josh Cogliati +diff --git a/sandbox/start b/sandbox/start +index 4ed3cb5c..3c1a1783 100644 +--- a/sandbox/start ++++ b/sandbox/start +@@ -1,4 +1,4 @@ +-#!/usr/bin/python3 -Es ++#!/usr/bin/python3 -EsI + try: + from subprocess import getstatusoutput + except ImportError: +-- +2.43.0 + diff --git a/SOURCES/0054-sepolicy-port-to-dnf4-python-API.patch b/SOURCES/0054-sepolicy-port-to-dnf4-python-API.patch new file mode 100644 index 0000000..587caea --- /dev/null +++ b/SOURCES/0054-sepolicy-port-to-dnf4-python-API.patch @@ -0,0 +1,95 @@ +From ea93da38a16eb44307b522f8a26f2d8f967fcc01 Mon Sep 17 00:00:00 2001 +From: Petr Lautrbach +Date: Wed, 22 Nov 2023 12:29:43 +0100 +Subject: [PATCH] sepolicy: port to dnf4 python API + +yum module is not available since RHEL 7. + +Drop -systemd related code as it's obsoleted these days - only 2 +packages ship their .service in -systemd subpackage + +Signed-off-by: Petr Lautrbach +Acked-by: James Carter +Acked-by: Ondrej Mosnacek +--- + python/sepolicy/sepolicy/generate.py | 56 +++++++++++++--------------- + 1 file changed, 25 insertions(+), 31 deletions(-) + +diff --git a/python/sepolicy/sepolicy/generate.py b/python/sepolicy/sepolicy/generate.py +index 93caedee..c841a499 100644 +--- a/python/sepolicy/sepolicy/generate.py ++++ b/python/sepolicy/sepolicy/generate.py +@@ -1265,24 +1265,20 @@ allow %s_t %s_t:%s_socket name_%s; + return fcfile + + def __extract_rpms(self): +- import yum +- yb = yum.YumBase() +- yb.setCacheDir() +- +- for pkg in yb.rpmdb.searchProvides(self.program): +- self.rpms.append(pkg.name) +- for fname in pkg.dirlist + pkg.filelist + pkg.ghostlist: +- for b in self.DEFAULT_DIRS: +- if b == "/etc": +- continue +- if fname.startswith(b): +- if os.path.isfile(fname): +- self.add_file(fname) +- else: +- self.add_dir(fname) ++ import dnf ++ ++ with dnf.Base() as base: ++ base.read_all_repos() ++ base.fill_sack(load_system_repo=True) ++ ++ query = base.sack.query() + +- for bpkg in yb.rpmdb.searchNames([pkg.base_package_name]): +- for fname in bpkg.dirlist + bpkg.filelist + bpkg.ghostlist: ++ pq = query.available() ++ pq = pq.filter(file=self.program) ++ ++ for pkg in pq: ++ self.rpms.append(pkg.name) ++ for fname in pkg.files: + for b in self.DEFAULT_DIRS: + if b == "/etc": + continue +@@ -1291,20 +1287,18 @@ allow %s_t %s_t:%s_socket name_%s; + self.add_file(fname) + else: + self.add_dir(fname) +- +- # some packages have own systemd subpackage +- # tor-systemd for example +- binary_name = self.program.split("/")[-1] +- for bpkg in yb.rpmdb.searchNames(["%s-systemd" % binary_name]): +- for fname in bpkg.filelist + bpkg.ghostlist + bpkg.dirlist: +- for b in self.DEFAULT_DIRS: +- if b == "/etc": +- continue +- if fname.startswith(b): +- if os.path.isfile(fname): +- self.add_file(fname) +- else: +- self.add_dir(fname) ++ sq = query.available() ++ sq = sq.filter(provides=pkg.source_name) ++ for bpkg in sq: ++ for fname in bpkg.files: ++ for b in self.DEFAULT_DIRS: ++ if b == "/etc": ++ continue ++ if fname.startswith(b): ++ if os.path.isfile(fname): ++ self.add_file(fname) ++ else: ++ self.add_dir(fname) + + def gen_writeable(self): + try: +-- +2.43.0 + diff --git a/SOURCES/0055-python-semanage-Do-not-sort-local-fcontext-definitio.patch b/SOURCES/0055-python-semanage-Do-not-sort-local-fcontext-definitio.patch new file mode 100644 index 0000000..f3f6b32 --- /dev/null +++ b/SOURCES/0055-python-semanage-Do-not-sort-local-fcontext-definitio.patch @@ -0,0 +1,64 @@ +From b6fa6e77d5d40a5c1b5f4be95500aa1a05147e5b Mon Sep 17 00:00:00 2001 +From: Vit Mojzis +Date: Wed, 7 Feb 2024 15:46:23 +0100 +Subject: [PATCH] python/semanage: Do not sort local fcontext definitions + +Entries in file_contexts.local are processed from the most recent one to +the oldest, with first match being used. Therefore it is important to +preserve their order when listing (semanage fcontext -lC) and exporting +(semanage export). + +Signed-off-by: Vit Mojzis +Acked-by: James Carter +--- + gui/fcontextPage.py | 6 +++++- + python/semanage/seobject.py | 9 +++++++-- + 2 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/gui/fcontextPage.py b/gui/fcontextPage.py +index e424366d..01a403a2 100644 +--- a/gui/fcontextPage.py ++++ b/gui/fcontextPage.py +@@ -125,7 +125,11 @@ class fcontextPage(semanagePage): + self.fcontext = seobject.fcontextRecords() + self.store.clear() + fcon_dict = self.fcontext.get_all(self.local) +- for k in sorted(fcon_dict.keys()): ++ if self.local: ++ fkeys = fcon_dict.keys() ++ else: ++ fkeys = sorted(fcon_dict.keys()) ++ for k in fkeys: + if not self.match(fcon_dict, k, filter): + continue + iter = self.store.append() +diff --git a/python/semanage/seobject.py b/python/semanage/seobject.py +index 0e923a0d..dd915a69 100644 +--- a/python/semanage/seobject.py ++++ b/python/semanage/seobject.py +@@ -2644,7 +2644,7 @@ class fcontextRecords(semanageRecords): + def customized(self): + l = [] + fcon_dict = self.get_all(True) +- for k in sorted(fcon_dict.keys()): ++ for k in fcon_dict.keys(): + if fcon_dict[k]: + if fcon_dict[k][3]: + l.append("-a -f %s -t %s -r '%s' '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], fcon_dict[k][3], k[0])) +@@ -2661,7 +2661,12 @@ class fcontextRecords(semanageRecords): + if len(fcon_dict) != 0: + if heading: + print("%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context"))) +- for k in sorted(fcon_dict.keys()): ++ # do not sort local customizations since they are evaluated based on the order they where added in ++ if locallist: ++ fkeys = fcon_dict.keys() ++ else: ++ fkeys = sorted(fcon_dict.keys()) ++ for k in fkeys: + if fcon_dict[k]: + if is_mls_enabled: + print("%-50s %-18s %s:%s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2], translate(fcon_dict[k][3], False))) +-- +2.43.0 + diff --git a/SOURCES/0056-python-semanage-Allow-modifying-records-on-add.patch b/SOURCES/0056-python-semanage-Allow-modifying-records-on-add.patch new file mode 100644 index 0000000..8a18710 --- /dev/null +++ b/SOURCES/0056-python-semanage-Allow-modifying-records-on-add.patch @@ -0,0 +1,396 @@ +From 108a7d43dd8fa4f5cb682f9df9c15304fa4eddea Mon Sep 17 00:00:00 2001 +From: Vit Mojzis +Date: Wed, 14 Feb 2024 13:08:40 +0100 +Subject: [PATCH] python/semanage: Allow modifying records on "add" + +When trying to add a record with a key that already exists, modify +the existing record instead. + +Also, fix "semanage -m -e" (add_equal was called instead of +modify_equal), which meant that existing local equivalency couldn't be +modified (though a user could remove it and add a modified +equivalency). + +Fixes: + https://github.com/SELinuxProject/selinux/issues/412 + When a port or login definition present in the policy is modified + using "semanage port -m", "semanage export" exports the command as + "port -a" instead of "port -m". This results in "semanage import" + failing (port already defined). The same is true for port, user, + login, ibpkey, ibendport, node, interface and fcontext. + +Signed-off-by: Vit Mojzis +Acked-by: James Carter +--- + python/semanage/semanage | 2 +- + python/semanage/seobject.py | 208 +++++++++++++++++++++++++----------- + 2 files changed, 147 insertions(+), 63 deletions(-) + +diff --git a/python/semanage/semanage b/python/semanage/semanage +index 1f170f60..f55751b6 100644 +--- a/python/semanage/semanage ++++ b/python/semanage/semanage +@@ -316,7 +316,7 @@ def handleFcontext(args): + OBJECT.add(args.file_spec, args.type, args.ftype, args.range, args.seuser) + if args.action == "modify": + if args.equal: +- OBJECT.add_equal(args.file_spec, args.equal) ++ OBJECT.modify_equal(args.file_spec, args.equal) + else: + OBJECT.modify(args.file_spec, args.type, args.ftype, args.range, args.seuser) + if args.action == "delete": +diff --git a/python/semanage/seobject.py b/python/semanage/seobject.py +index dd915a69..f6c559a7 100644 +--- a/python/semanage/seobject.py ++++ b/python/semanage/seobject.py +@@ -560,11 +560,6 @@ class loginRecords(semanageRecords): + if rc < 0: + raise ValueError(_("Could not create a key for %s") % name) + +- (rc, exists) = semanage_seuser_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if login mapping for %s is defined") % name) +- if exists: +- raise ValueError(_("Login mapping for %s is already defined") % name) + if name[0] == '%': + try: + grp.getgrnam(name[1:]) +@@ -603,11 +598,29 @@ class loginRecords(semanageRecords): + def add(self, name, sename, serange): + try: + self.begin() +- self.__add(name, sename, serange) ++ # Add a new mapping, or modify an existing one ++ if self.__exists(name): ++ print(_("Login mapping for %s is already defined, modifying instead") % name) ++ self.__modify(name, sename, serange) ++ else: ++ self.__add(name, sename, serange) + self.commit() + except ValueError as error: + raise error + ++ # check if login mapping for given user exists ++ def __exists(self, name): ++ (rc, k) = semanage_seuser_key_create(self.sh, name) ++ if rc < 0: ++ raise ValueError(_("Could not create a key for %s") % name) ++ ++ (rc, exists) = semanage_seuser_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if login mapping for %s is defined") % name) ++ semanage_seuser_key_free(k) ++ ++ return exists ++ + def __modify(self, name, sename="", serange=""): + rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name) + if sename == "" and serange == "": +@@ -824,12 +837,6 @@ class seluserRecords(semanageRecords): + if rc < 0: + raise ValueError(_("Could not create a key for %s") % name) + +- (rc, exists) = semanage_user_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if SELinux user %s is defined") % name) +- if exists: +- raise ValueError(_("SELinux user %s is already defined") % name) +- + (rc, u) = semanage_user_create(self.sh) + if rc < 0: + raise ValueError(_("Could not create SELinux user for %s") % name) +@@ -869,12 +876,28 @@ class seluserRecords(semanageRecords): + def add(self, name, roles, selevel, serange, prefix): + try: + self.begin() +- self.__add(name, roles, selevel, serange, prefix) ++ if self.__exists(name): ++ print(_("SELinux user %s is already defined, modifying instead") % name) ++ self.__modify(name, roles, selevel, serange, prefix) ++ else: ++ self.__add(name, roles, selevel, serange, prefix) + self.commit() + except ValueError as error: + self.mylog.commit(0) + raise error + ++ def __exists(self, name): ++ (rc, k) = semanage_user_key_create(self.sh, name) ++ if rc < 0: ++ raise ValueError(_("Could not create a key for %s") % name) ++ ++ (rc, exists) = semanage_user_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if SELinux user %s is defined") % name) ++ semanage_user_key_free(k) ++ ++ return exists ++ + def __modify(self, name, roles=[], selevel="", serange="", prefix=""): + oldserole = "" + oldserange = "" +@@ -1102,12 +1125,6 @@ class portRecords(semanageRecords): + + (k, proto_d, low, high) = self.__genkey(port, proto) + +- (rc, exists) = semanage_port_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port)) +- if exists: +- raise ValueError(_("Port %s/%s already defined") % (proto, port)) +- + (rc, p) = semanage_port_create(self.sh) + if rc < 0: + raise ValueError(_("Could not create port for %s/%s") % (proto, port)) +@@ -1151,9 +1168,23 @@ class portRecords(semanageRecords): + + def add(self, port, proto, serange, type): + self.begin() +- self.__add(port, proto, serange, type) ++ if self.__exists(port, proto): ++ print(_("Port {proto}/{port} already defined, modifying instead").format(proto=proto, port=port)) ++ self.__modify(port, proto, serange, type) ++ else: ++ self.__add(port, proto, serange, type) + self.commit() + ++ def __exists(self, port, proto): ++ (k, proto_d, low, high) = self.__genkey(port, proto) ++ ++ (rc, exists) = semanage_port_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if port {proto}/{port} is defined").format(proto=proto, port=port)) ++ semanage_port_key_free(k) ++ ++ return exists ++ + def __modify(self, port, proto, serange, setype): + if serange == "" and setype == "": + if is_mls_enabled == 1: +@@ -1376,12 +1407,6 @@ class ibpkeyRecords(semanageRecords): + + (k, subnet_prefix, low, high) = self.__genkey(pkey, subnet_prefix) + +- (rc, exists) = semanage_ibpkey_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if ibpkey %s/%s is defined") % (subnet_prefix, pkey)) +- if exists: +- raise ValueError(_("ibpkey %s/%s already defined") % (subnet_prefix, pkey)) +- + (rc, p) = semanage_ibpkey_create(self.sh) + if rc < 0: + raise ValueError(_("Could not create ibpkey for %s/%s") % (subnet_prefix, pkey)) +@@ -1423,9 +1448,23 @@ class ibpkeyRecords(semanageRecords): + + def add(self, pkey, subnet_prefix, serange, type): + self.begin() +- self.__add(pkey, subnet_prefix, serange, type) ++ if self.__exists(pkey, subnet_prefix): ++ print(_("ibpkey {subnet_prefix}/{pkey} already defined, modifying instead").format(subnet_prefix=subnet_prefix, pkey=pkey)) ++ self.__modify(pkey, subnet_prefix, serange, type) ++ else: ++ self.__add(pkey, subnet_prefix, serange, type) + self.commit() + ++ def __exists(self, pkey, subnet_prefix): ++ (k, subnet_prefix, low, high) = self.__genkey(pkey, subnet_prefix) ++ ++ (rc, exists) = semanage_ibpkey_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if ibpkey {subnet_prefix}/{pkey} is defined").formnat(subnet_prefix=subnet_prefix, pkey=pkey)) ++ semanage_ibpkey_key_free(k) ++ ++ return exists ++ + def __modify(self, pkey, subnet_prefix, serange, setype): + if serange == "" and setype == "": + if is_mls_enabled == 1: +@@ -1630,12 +1669,6 @@ class ibendportRecords(semanageRecords): + raise ValueError(_("Type %s is invalid, must be an ibendport type") % type) + (k, ibendport, port) = self.__genkey(ibendport, ibdev_name) + +- (rc, exists) = semanage_ibendport_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if ibendport %s/%s is defined") % (ibdev_name, port)) +- if exists: +- raise ValueError(_("ibendport %s/%s already defined") % (ibdev_name, port)) +- + (rc, p) = semanage_ibendport_create(self.sh) + if rc < 0: + raise ValueError(_("Could not create ibendport for %s/%s") % (ibdev_name, port)) +@@ -1677,9 +1710,23 @@ class ibendportRecords(semanageRecords): + + def add(self, ibendport, ibdev_name, serange, type): + self.begin() +- self.__add(ibendport, ibdev_name, serange, type) ++ if self.__exists(ibendport, ibdev_name): ++ print(_("ibendport {ibdev_name}/{port} already defined, modifying instead").format(ibdev_name=ibdev_name, port=port)) ++ self.__modify(ibendport, ibdev_name, serange, type) ++ else: ++ self.__add(ibendport, ibdev_name, serange, type) + self.commit() + ++ def __exists(self, ibendport, ibdev_name): ++ (k, ibendport, port) = self.__genkey(ibendport, ibdev_name) ++ ++ (rc, exists) = semanage_ibendport_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if ibendport {ibdev_name}/{port} is defined").format(ibdev_name=ibdev_name, port=port)) ++ semanage_ibendport_key_free(k) ++ ++ return exists ++ + def __modify(self, ibendport, ibdev_name, serange, setype): + if serange == "" and setype == "": + if is_mls_enabled == 1: +@@ -1891,12 +1938,6 @@ class nodeRecords(semanageRecords): + (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) + if rc < 0: + raise ValueError(_("Could not create key for %s") % addr) +- if rc < 0: +- raise ValueError(_("Could not check if addr %s is defined") % addr) +- +- (rc, exists) = semanage_node_exists(self.sh, k) +- if exists: +- raise ValueError(_("Addr %s already defined") % addr) + + (rc, node) = semanage_node_create(self.sh) + if rc < 0: +@@ -1945,9 +1986,27 @@ class nodeRecords(semanageRecords): + + def add(self, addr, mask, proto, serange, ctype): + self.begin() +- self.__add(addr, mask, proto, serange, ctype) ++ if self.__exists(addr, mask, proto): ++ print(_("Addr %s already defined, modifying instead") % addr) ++ self.__modify(addr, mask, proto, serange, ctype) ++ else: ++ self.__add(addr, mask, proto, serange, ctype) + self.commit() + ++ def __exists(self, addr, mask, proto): ++ addr, mask, proto = self.validate(addr, mask, proto) ++ ++ (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto) ++ if rc < 0: ++ raise ValueError(_("Could not create key for %s") % addr) ++ ++ (rc, exists) = semanage_node_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if addr %s is defined") % addr) ++ semanage_node_key_free(k) ++ ++ return exists ++ + def __modify(self, addr, mask, proto, serange, setype): + addr, mask, proto = self.validate(addr, mask, proto) + +@@ -2102,12 +2161,6 @@ class interfaceRecords(semanageRecords): + if rc < 0: + raise ValueError(_("Could not create key for %s") % interface) + +- (rc, exists) = semanage_iface_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if interface %s is defined") % interface) +- if exists: +- raise ValueError(_("Interface %s already defined") % interface) +- + (rc, iface) = semanage_iface_create(self.sh) + if rc < 0: + raise ValueError(_("Could not create interface for %s") % interface) +@@ -2154,9 +2207,25 @@ class interfaceRecords(semanageRecords): + + def add(self, interface, serange, ctype): + self.begin() +- self.__add(interface, serange, ctype) ++ if self.__exists(interface): ++ print(_("Interface %s already defined, modifying instead") % interface) ++ self.__modify(interface, serange, ctype) ++ else: ++ self.__add(interface, serange, ctype) + self.commit() + ++ def __exists(self, interface): ++ (rc, k) = semanage_iface_key_create(self.sh, interface) ++ if rc < 0: ++ raise ValueError(_("Could not create key for %s") % interface) ++ ++ (rc, exists) = semanage_iface_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if interface %s is defined") % interface) ++ semanage_iface_key_free(k) ++ ++ return exists ++ + def __modify(self, interface, serange, setype): + if serange == "" and setype == "": + raise ValueError(_("Requires setype or serange")) +@@ -2344,7 +2413,13 @@ class fcontextRecords(semanageRecords): + raise ValueError(_("Substitute %s is not valid. Substitute is not allowed to end with '/'") % substitute) + + if target in self.equiv.keys(): +- raise ValueError(_("Equivalence class for %s already exists") % target) ++ print(_("Equivalence class for %s already exists, modifying instead") % target) ++ self.equiv[target] = substitute ++ self.equal_ind = True ++ self.mylog.log_change("resrc=fcontext op=modify-equal %s %s" % (audit.audit_encode_nv_string("sglob", target, 0), audit.audit_encode_nv_string("tglob", substitute, 0))) ++ self.commit() ++ return ++ + self.validate(target) + + for fdict in (self.equiv, self.equiv_dist): +@@ -2420,18 +2495,6 @@ class fcontextRecords(semanageRecords): + if rc < 0: + raise ValueError(_("Could not create key for %s") % target) + +- (rc, exists) = semanage_fcontext_exists(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if file context for %s is defined") % target) +- +- if not exists: +- (rc, exists) = semanage_fcontext_exists_local(self.sh, k) +- if rc < 0: +- raise ValueError(_("Could not check if file context for %s is defined") % target) +- +- if exists: +- raise ValueError(_("File context for %s already defined") % target) +- + (rc, fcontext) = semanage_fcontext_create(self.sh) + if rc < 0: + raise ValueError(_("Could not create file context for %s") % target) +@@ -2470,9 +2533,30 @@ class fcontextRecords(semanageRecords): + + def add(self, target, type, ftype="", serange="", seuser="system_u"): + self.begin() +- self.__add(target, type, ftype, serange, seuser) ++ if self.__exists(target, ftype): ++ print(_("File context for %s already defined, modifying instead") % target) ++ self.__modify(target, type, ftype, serange, seuser) ++ else: ++ self.__add(target, type, ftype, serange, seuser) + self.commit() + ++ def __exists(self, target, ftype): ++ (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) ++ if rc < 0: ++ raise ValueError(_("Could not create key for %s") % target) ++ ++ (rc, exists) = semanage_fcontext_exists(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if file context for %s is defined") % target) ++ ++ if not exists: ++ (rc, exists) = semanage_fcontext_exists_local(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not check if file context for %s is defined") % target) ++ semanage_fcontext_key_free(k) ++ ++ return exists ++ + def __modify(self, target, setype, ftype, serange, seuser): + if serange == "" and setype == "" and seuser == "": + raise ValueError(_("Requires setype, serange or seuser")) +-- +2.43.0 + diff --git a/SPECS/policycoreutils.spec b/SPECS/policycoreutils.spec index 4abbf9d..4044af5 100644 --- a/SPECS/policycoreutils.spec +++ b/SPECS/policycoreutils.spec @@ -12,7 +12,7 @@ Summary: SELinux policy core utilities Name: policycoreutils Version: 2.9 -Release: 24%{?dist} +Release: 26%{?dist} License: GPLv2 # https://github.com/SELinuxProject/selinux/wiki/Releases Source0: https://github.com/SELinuxProject/selinux/releases/download/20190315/policycoreutils-2.9.tar.gz @@ -90,6 +90,10 @@ Patch0049: 0049-python-Harden-tools-against-rogue-modules.patch Patch0050: 0050-python-Do-not-query-the-local-database-if-the-fconte.patch Patch0051: 0051-python-sepolicy-add-missing-booleans-to-man-pages.patch Patch0052: 0052-python-sepolicy-Cache-conditional-rule-queries.patch +Patch0053: 0053-python-Harden-more-tools-against-rogue-modules.patch +Patch0054: 0054-sepolicy-port-to-dnf4-python-API.patch +Patch0056: 0055-python-semanage-Do-not-sort-local-fcontext-definitio.patch +Patch0057: 0056-python-semanage-Allow-modifying-records-on-add.patch Obsoletes: policycoreutils < 2.0.61-2 Conflicts: filesystem < 3, selinux-policy-base < 3.13.1-138 @@ -529,6 +533,14 @@ The policycoreutils-restorecond package contains the restorecond service. %systemd_postun_with_restart restorecond.service %changelog +* Wed Mar 06 2024 Vit Mojzis - 2.9-26 +- python/semanage: Allow modifying records on "add" (RHEL-28167) +- python/semanage: Do not sort local fcontext definitions (RHEL-24461) + +* Tue Feb 06 2024 Vit Mojzis - 2.9-25 +- Harden more tools against "rogue" modules (RHEL-17351) +- sepolicy: port to dnf4 python API (RHEL-17398) + * Wed Jul 26 2023 MSVSphere Packaging Team - 2.9-24 - Rebuilt for MSVSphere 8.8