From f46b044e34950f270af3c7d3eb42dd1bf4f9a872 Mon Sep 17 00:00:00 2001 From: Vit Mojzis Date: Tue, 7 Oct 2025 12:26:46 +0200 Subject: [PATCH] policycoreutils-3.9-2 - semanage: Reset active value when deleting boolean customizations (RHEL-111421) - setfiles: Add -A option to disable SELINUX_RESTORECON_ADD_ASSOC (RHEL-111505) Resolves: RHEL-111421, RHEL-111505 --- ...ption-to-disable-SELINUX_RESTORECON_.patch | 91 +++++++++++++++++ ...ctive-value-when-deleting-boolean-cu.patch | 98 +++++++++++++++++++ changelog | 4 + policycoreutils.spec | 4 +- 4 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 0007-setfiles-Add-A-option-to-disable-SELINUX_RESTORECON_.patch create mode 100644 0008-semanage-Reset-active-value-when-deleting-boolean-cu.patch diff --git a/0007-setfiles-Add-A-option-to-disable-SELINUX_RESTORECON_.patch b/0007-setfiles-Add-A-option-to-disable-SELINUX_RESTORECON_.patch new file mode 100644 index 0000000..e8ec6ff --- /dev/null +++ b/0007-setfiles-Add-A-option-to-disable-SELINUX_RESTORECON_.patch @@ -0,0 +1,91 @@ +From ae251cfb85090126d5c1de62b94775fae3b43527 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 10 Sep 2025 11:42:09 +0100 +Subject: [PATCH] setfiles: Add -A option to disable + SELINUX_RESTORECON_ADD_ASSOC + +SELINUX_RESTORECON_ADD_ASSOC tracks conflicts between inodes with +multiple hard links or bind mounts that have differing contexts. +However doing this involves building a large internal hashtable that +stores the full path of every file examined by setfiles. For +filesystems that have very large numbers of files or long pathnames, +this uses a lot of memory, which makes SELinux relabelling in +constrained memory environments infeasible. + +This adds a new setfiles -A option that disables this tracking. + +For example, using setfiles to relabel a filesystem with 15 million +files took 3.7GB of RAM. Using this option, the same filesystem can +be relabelled in 121MB (albeit with no warnings or errors possible for +conflicting labels, but for our use case we don't care about that.) + +Fixes: https://issues.redhat.com/browse/RHEL-111505 +Signed-off-by: Richard W.M. Jones +Acked-by: Stephen Smalley +--- + policycoreutils/setfiles/setfiles.8 | 5 +++++ + policycoreutils/setfiles/setfiles.c | 11 +++++++---- + 2 files changed, 12 insertions(+), 4 deletions(-) + +diff --git a/policycoreutils/setfiles/setfiles.8 b/policycoreutils/setfiles/setfiles.8 +index 187f4513..458f3f9f 100644 +--- a/policycoreutils/setfiles/setfiles.8 ++++ b/policycoreutils/setfiles/setfiles.8 +@@ -23,6 +23,7 @@ setfiles \- set SELinux file security contexts. + .RB [ \-I | \-D ] + .RB [ \-T + .IR nthreads ] ++.RB [ \-A ] + .I spec_file + .IR pathname \ ... + +@@ -187,6 +188,10 @@ use up to + threads. Specify 0 to create as many threads as there are available + CPU cores; 1 to use only a single thread (default); or any positive + number to use the given number of threads (if possible). ++.TP ++.B \-A ++do not track inodes with multiple hard links or bind mounts that would ++match different contexts (saves memory) + + .SH "ARGUMENTS" + .TP +diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c +index ad09f840..31034316 100644 +--- a/policycoreutils/setfiles/setfiles.c ++++ b/policycoreutils/setfiles/setfiles.c +@@ -40,9 +40,9 @@ static __attribute__((__noreturn__)) void usage(const char *const name) + name, name); + } else { + fprintf(stderr, +- "usage: %s [-diIDlmnpqvCEFUWT] [-e excludedir] [-r alt_root_path] [-c policyfile] spec_file pathname...\n" +- "usage: %s [-diIDlmnpqvCEFUWT] [-e excludedir] [-r alt_root_path] [-c policyfile] spec_file -f filename\n" +- "usage: %s -s [-diIDlmnpqvFUWT] spec_file\n", ++ "usage: %s [-diIDlmnpqvACEFUWT] [-e excludedir] [-r alt_root_path] [-c policyfile] spec_file pathname...\n" ++ "usage: %s [-diIDlmnpqvACEFUWT] [-e excludedir] [-r alt_root_path] [-c policyfile] spec_file -f filename\n" ++ "usage: %s -s [-diIDlmnpqvAFUWT] spec_file\n", + name, name, name); + } + exit(-1); +@@ -147,7 +147,7 @@ int main(int argc, char **argv) + const char *base; + int errors = 0; + const char *ropts = "e:f:hiIDlmno:pqrsvFURW0xT:"; +- const char *sopts = "c:de:f:hiIDlmno:pqr:svCEFUR:W0T:"; ++ const char *sopts = "c:de:f:hiIDlmno:pqr:svACEFUR:W0T:"; + const char *opts; + union selinux_callback cb; + long unsigned skipped_errors; +@@ -375,6 +375,9 @@ int main(int argc, char **argv) + if (*optarg == '\0' || *endptr != '\0') + usage(argv[0]); + break; ++ case 'A': ++ r_opts.add_assoc = 0; ++ break; + case 'h': + case '?': + usage(argv[0]); +-- +2.49.0 + diff --git a/0008-semanage-Reset-active-value-when-deleting-boolean-cu.patch b/0008-semanage-Reset-active-value-when-deleting-boolean-cu.patch new file mode 100644 index 0000000..470fde9 --- /dev/null +++ b/0008-semanage-Reset-active-value-when-deleting-boolean-cu.patch @@ -0,0 +1,98 @@ +From c1bd6ee62f2cedfb3709710fc46f2899b301c139 Mon Sep 17 00:00:00 2001 +From: Vit Mojzis +Date: Mon, 1 Sep 2025 18:17:10 +0200 +Subject: [PATCH] semanage: Reset active value when deleting boolean + customizations + +Currently, removal of boolean local customizations leaves their current +(active) value untouched. + +After the removal is complete, semanage_bool_query will return the +default value. But it needs to be called in a separate transaction. +This makes the fix a bit awkward, but I have not found a way to query +the default value before the first transation is committed. + +Fixes: + # getsebool smbd_anon_write + smbd_anon_write --> off + # semanage boolean -m1 smbd_anon_write + # semanage boolean -D + # getsebool smbd_anon_write + smbd_anon_write --> on + # manage boolean -l isemanage boolean --list | grep smbd_anon_write + smbd_anon_write (on , off) Allow smbd to anon write + +Signed-off-by: Vit Mojzis +--- + python/semanage/seobject.py | 43 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +diff --git a/python/semanage/seobject.py b/python/semanage/seobject.py +index 10963e81..6d6188fd 100644 +--- a/python/semanage/seobject.py ++++ b/python/semanage/seobject.py +@@ -2886,7 +2886,15 @@ class booleanRecords(semanageRecords): + self.__delete(name) + self.commit() + ++ # New transaction to reset the boolean to its default value. ++ # Calling __reset_value in the same transaction as the removal of ++ # local customizations does nothing ++ self.begin() ++ self.__reset_value(name) ++ self.commit() ++ + def deleteall(self): ++ deleted = [] + (rc, self.blist) = semanage_bool_list_local(self.sh) + if rc < 0: + raise ValueError(_("Could not list booleans")) +@@ -2895,10 +2903,45 @@ class booleanRecords(semanageRecords): + + for boolean in self.blist: + name = semanage_bool_get_name(boolean) ++ deleted.append(name) + self.__delete(name) + + self.commit() + ++ # New transaction to reset all affected booleans to their default values. ++ # Calling __reset_value in the same transaction as the removal of ++ # local customizations does nothing ++ self.begin() ++ ++ for boolean in deleted: ++ self.__reset_value(boolean) ++ ++ self.commit() ++ ++ # Set active value to default ++ # Note: this needs to be called in a new transaction after removing local customizations ++ # in order for semanage_bool_query to fetch the default value ++ # (as opposed to the current one -- set by the local customizations) ++ def __reset_value(self, name): ++ name = selinux.selinux_boolean_sub(name) ++ ++ (rc, k) = semanage_bool_key_create(self.sh, name) ++ if rc < 0: ++ raise ValueError(_("Could not create a key for %s") % name) ++ ++ (rc, b) = semanage_bool_query(self.sh, k) ++ if rc < 0: ++ raise ValueError(_("Could not query boolean %s") % name) ++ ++ semanage_bool_set_value(b, semanage_bool_get_value(b)) ++ ++ rc = semanage_bool_set_active(self.sh, k, b) ++ if rc < 0: ++ raise ValueError(_("Could not set active value of boolean %s") % name) ++ ++ semanage_bool_key_free(k) ++ semanage_bool_free(b) ++ + def get_all(self, locallist=0): + ddict = {} + if locallist: +-- +2.49.0 + diff --git a/changelog b/changelog index 92fceab..2ac5556 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,7 @@ +* Tue Oct 07 2025 Vit Mojzis - 3.9-2 +- semanage: Reset active value when deleting boolean customizations (RHEL-111421) +- setfiles: Add -A option to disable SELINUX_RESTORECON_ADD_ASSOC (RHEL-111505) + * Wed Jul 23 2025 Vit Mojzis - 3.9-1 - SELinux userspace 3.9 release diff --git a/policycoreutils.spec b/policycoreutils.spec index 456a3f2..4cc1551 100644 --- a/policycoreutils.spec +++ b/policycoreutils.spec @@ -11,7 +11,7 @@ Summary: SELinux policy core utilities Name: policycoreutils Version: 3.9 -Release: 1%{?dist} +Release: 2%{?dist} License: GPL-2.0-or-later # https://github.com/SELinuxProject/selinux/wiki/Releases Source0: https://github.com/SELinuxProject/selinux/releases/download/%{version}/selinux-%{version}.tar.gz @@ -44,6 +44,8 @@ Patch0003: 0003-sandbox-Use-matchbox-window-manager-instead-of-openb.patch Patch0004: 0004-Use-SHA-2-instead-of-SHA-1.patch Patch0005: 0005-python-sepolicy-Fix-spec-file-dependencies.patch Patch0006: 0006-sepolicy-Fix-detection-of-writeable-locations.patch +Patch0007: 0007-setfiles-Add-A-option-to-disable-SELINUX_RESTORECON_.patch +Patch0008: 0008-semanage-Reset-active-value-when-deleting-boolean-cu.patch # Patch list end Obsoletes: policycoreutils < 2.0.61-2