SELinux userspace 3.10 release

Resolves: RHEL-144828
This commit is contained in:
Vit Mojzis 2026-02-06 17:04:25 +01:00
parent 0a35929811
commit 23f1664a75
14 changed files with 623 additions and 582 deletions

2
.gitignore vendored
View File

@ -367,3 +367,5 @@ policycoreutils-2.0.83.tgz
/selinux-3.9-rc2.tar.gz.asc
/selinux-3.9.tar.gz
/selinux-3.9.tar.gz.asc
/selinux-3.10.tar.gz
/selinux-3.10.tar.gz.asc

View File

@ -1,4 +1,4 @@
From ce28d432bef8d1a346054b56a989e58533fecfa7 Mon Sep 17 00:00:00 2001
From 966537fe43b84f19153592ad946384b80deda37e Mon Sep 17 00:00:00 2001
From: Dan Walsh <dwalsh@redhat.com>
Date: Fri, 14 Feb 2014 12:32:12 -0500
Subject: [PATCH] Don't be verbose if you are not on a tty
@ -20,5 +20,5 @@ index b7cd765c..f2518e96 100755
THREADS=""
RPMFILES=""
--
2.49.0
2.52.0

View File

@ -1,4 +1,4 @@
From 618ae48ebf1334f9380a9ae7460c553515f9c4ca Mon Sep 17 00:00:00 2001
From 3bdc320b86f6694e3716941899a6fca0aff8f9ae Mon Sep 17 00:00:00 2001
From: Masatake YAMATO <yamato@redhat.com>
Date: Thu, 14 Dec 2017 15:57:58 +0900
Subject: [PATCH] sepolicy-generate: Handle more reserved port types
@ -52,7 +52,7 @@ https://lore.kernel.org/selinux/20150610.190635.1866127952891120915.yamato@redha
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/python/sepolicy/sepolicy/generate.py b/python/sepolicy/sepolicy/generate.py
index adf65f27..f726ad51 100644
index 780a56b2..cde6a840 100644
--- a/python/sepolicy/sepolicy/generate.py
+++ b/python/sepolicy/sepolicy/generate.py
@@ -100,7 +100,9 @@ def get_all_ports():
@ -67,5 +67,5 @@ index adf65f27..f726ad51 100644
dict[(p['low'], p['high'], p['protocol'])] = (p['type'], p.get('range'))
return dict
--
2.49.0
2.52.0

View File

@ -1,4 +1,4 @@
From 16fd581da479f80b8f8ff8ae8ff58a4f0a610d54 Mon Sep 17 00:00:00 2001
From d1b75aa6f0cd9c45f025bb619821183446ebfe28 Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <plautrba@redhat.com>
Date: Wed, 18 Jul 2018 09:09:35 +0200
Subject: [PATCH] sandbox: Use matchbox-window-manager instead of openbox
@ -70,5 +70,5 @@ index 28169182..e2a7ad9b 100644
if [ -z "$WAYLAND_DISPLAY" ]; then
DISPLAY_COMMAND='/usr/bin/Xephyr -resizeable -title "$TITLE" -terminate -screen $SCREENSIZE -dpi $DPI -nolisten tcp -displayfd 5 5>&1 2>/dev/null'
--
2.49.0
2.52.0

View File

@ -1,4 +1,4 @@
From 1a3fc195c6dc7fe51ef76e4484910f7b41161ccc Mon Sep 17 00:00:00 2001
From 74f566f16de93662e022d37d616a2f5f47f27f45 Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <plautrba@redhat.com>
Date: Fri, 30 Jul 2021 14:14:37 +0200
Subject: [PATCH] Use SHA-2 instead of SHA-1
@ -12,7 +12,7 @@ The use of SHA-1 in RHEL9 is deprecated
4 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/policycoreutils/setfiles/restorecon.8 b/policycoreutils/setfiles/restorecon.8
index 1134420e..77dd0542 100644
index b7ff9715..66b9c800 100644
--- a/policycoreutils/setfiles/restorecon.8
+++ b/policycoreutils/setfiles/restorecon.8
@@ -103,14 +103,14 @@ display usage information and exit.
@ -33,7 +33,7 @@ index 1134420e..77dd0542 100644
enable usage of the
.IR security.sehash
extended attribute.
@@ -208,7 +208,7 @@ the
@@ -211,7 +211,7 @@ the
.B \-D
option to
.B restorecon
@ -42,7 +42,7 @@ index 1134420e..77dd0542 100644
attribute named
.IR security.sehash
on each directory specified in
@@ -225,7 +225,7 @@ for further details.
@@ -228,7 +228,7 @@ for further details.
.sp
The
.B \-I
@ -133,10 +133,10 @@ index 31fb82fd..bc22d3fd 100644
}
diff --git a/policycoreutils/setfiles/setfiles.8 b/policycoreutils/setfiles/setfiles.8
index eabf0a1c..187f4513 100644
index d43e4ad2..458f3f9f 100644
--- a/policycoreutils/setfiles/setfiles.8
+++ b/policycoreutils/setfiles/setfiles.8
@@ -104,14 +104,14 @@ display usage information and exit.
@@ -105,14 +105,14 @@ display usage information and exit.
ignore files that do not exist.
.TP
.B \-I
@ -154,7 +154,7 @@ index eabf0a1c..187f4513 100644
enable usage of the
.IR security.sehash
extended attribute.
@@ -270,7 +270,7 @@ the
@@ -275,7 +275,7 @@ the
.B \-D
option to
.B setfiles
@ -163,7 +163,7 @@ index eabf0a1c..187f4513 100644
.B spec_file
set in an extended attribute named
.IR security.sehash
@@ -291,7 +291,7 @@ for further details.
@@ -296,7 +296,7 @@ for further details.
.sp
The
.B \-I
@ -173,5 +173,5 @@ index eabf0a1c..187f4513 100644
and provided the
.B \-n
--
2.49.0
2.52.0

View File

@ -1,4 +1,4 @@
From 84b051139ab536519cc8e9c333483475d830d40b Mon Sep 17 00:00:00 2001
From 4d7b6cd22b09eec515e73bc26a640d888a222a9c Mon Sep 17 00:00:00 2001
From: Vit Mojzis <vmojzis@redhat.com>
Date: Tue, 30 May 2023 09:07:28 +0200
Subject: [PATCH] python/sepolicy: Fix spec file dependencies
@ -43,5 +43,5 @@ index 433c298a..a6d4508b 100644
mid_section="""\
--
2.49.0
2.52.0

View File

@ -1,4 +1,4 @@
From 98cd707e8106e9e77b179bccbeb4fd4004b4c601 Mon Sep 17 00:00:00 2001
From 7bc3e35c8c8e158e8cba30f7dd42e6a68a8378b3 Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <lautrbach@redhat.com>
Date: Mon, 5 May 2025 18:28:40 +0200
Subject: [PATCH] sepolicy: Fix detection of writeable locations
@ -29,10 +29,10 @@ Signed-off-by: Petr Lautrbach <lautrbach@redhat.com>
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/python/sepolicy/sepolicy/generate.py b/python/sepolicy/sepolicy/generate.py
index f726ad51..a0314a70 100644
index cde6a840..9b360e96 100644
--- a/python/sepolicy/sepolicy/generate.py
+++ b/python/sepolicy/sepolicy/generate.py
@@ -1267,15 +1267,15 @@ allow %s_t %s_t:%s_socket name_%s;
@@ -1324,15 +1324,15 @@ allow %s_t %s_t:%s_socket name_%s;
import dnf
with dnf.Base() as base:
@ -51,7 +51,7 @@ index f726ad51..a0314a70 100644
self.rpms.append(pkg.name)
for fname in pkg.files:
for b in self.DEFAULT_DIRS:
@@ -1288,7 +1288,7 @@ allow %s_t %s_t:%s_socket name_%s;
@@ -1345,7 +1345,7 @@ allow %s_t %s_t:%s_socket name_%s;
self.add_dir(fname)
sq = query.available()
sq = sq.filter(provides=pkg.source_name)
@ -61,5 +61,5 @@ index f726ad51..a0314a70 100644
for b in self.DEFAULT_DIRS:
if b == "/etc":
--
2.49.0
2.52.0

View File

@ -1,91 +0,0 @@
From ae251cfb85090126d5c1de62b94775fae3b43527 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
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 <rjones@redhat.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
---
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

View File

@ -1,98 +0,0 @@
From c1bd6ee62f2cedfb3709710fc46f2899b301c139 Mon Sep 17 00:00:00 2001
From: Vit Mojzis <vmojzis@redhat.com>
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 <vmojzis@redhat.com>
---
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

View File

@ -1,356 +0,0 @@
From 54cbd31a219790932364d8b79f9a459ea3276bcf Mon Sep 17 00:00:00 2001
From: Vit Mojzis <vmojzis@redhat.com>
Date: Fri, 7 Nov 2025 18:41:36 +0100
Subject: [PATCH] restorecon: Add option to count relabeled files
This is useful in case we want to check that a remediation using
restorecon was successful (otherwise 0 is always returned, even if no
files were relabeled).
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
---
libselinux/include/selinux/restorecon.h | 15 +++++++++++
libselinux/src/libselinux.map | 5 ++++
libselinux/src/selinux_restorecon.c | 34 ++++++++++++++++++++++---
policycoreutils/setfiles/restore.c | 12 ++++++---
policycoreutils/setfiles/restore.h | 3 ++-
policycoreutils/setfiles/restorecon.8 | 3 +++
policycoreutils/setfiles/setfiles.c | 26 ++++++++++++++-----
7 files changed, 83 insertions(+), 15 deletions(-)
diff --git a/libselinux/include/selinux/restorecon.h b/libselinux/include/selinux/restorecon.h
index 8dcc831b..aca218dc 100644
--- a/libselinux/include/selinux/restorecon.h
+++ b/libselinux/include/selinux/restorecon.h
@@ -134,6 +134,11 @@ extern int selinux_restorecon_parallel(const char *pathname,
*/
#define SELINUX_RESTORECON_SET_USER_ROLE 0x40000
+/*
+ * Count the number of relabeled files (or would be relabeled if "nochange" was not set).
+ */
+#define SELINUX_RESTORECON_COUNT_RELABELED 0x80000
+
/**
* selinux_restorecon_set_sehandle - Set the global fc handle.
* @hndl: specifies handle to set as the global fc handle.
@@ -228,6 +233,16 @@ extern int selinux_restorecon_xattr(const char *pathname,
*/
extern long unsigned selinux_restorecon_get_skipped_errors(void);
+/* selinux_restorecon_get_relabeled_files - Get the number of relabeled files
+ *
+ * If SELINUX_RESTORECON_COUNT_RELABELED was passed to selinux_restorecon(3) or
+ * selinux_restorecon_parallel(3), this function returns the number of files
+ * that were successfully relabeled.
+ * If the SELINUX_RESTORECON_NOCHANGE flag was set, this function returns
+ * the number of files that would be relabeled.
+ */
+extern long unsigned selinux_restorecon_get_relabeled_files(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/libselinux/src/libselinux.map b/libselinux/src/libselinux.map
index ab002f01..95cd53b0 100644
--- a/libselinux/src/libselinux.map
+++ b/libselinux/src/libselinux.map
@@ -262,3 +262,8 @@ LIBSELINUX_3.9 {
global:
context_to_str;
} LIBSELINUX_3.8;
+
+LIBSELINUX_3.10 {
+ global:
+ selinux_restorecon_get_relabeled_files;
+} LIBSELINUX_3.9;
diff --git a/libselinux/src/selinux_restorecon.c b/libselinux/src/selinux_restorecon.c
index 23546cb0..28749ee2 100644
--- a/libselinux/src/selinux_restorecon.c
+++ b/libselinux/src/selinux_restorecon.c
@@ -69,6 +69,9 @@ static struct dir_xattr *dir_xattr_last;
/* Number of errors ignored during the file tree walk. */
static long unsigned skipped_errors;
+/* Number of successfully relabeled files or files that would be relabeled */
+static long unsigned relabeled_files;
+
/* restorecon_flags for passing to restorecon_sb() */
struct rest_flags {
bool nochange;
@@ -88,6 +91,7 @@ struct rest_flags {
bool warnonnomatch;
bool conflicterror;
bool count_errors;
+ bool count_relabeled;
};
static void restorecon_init(void)
@@ -650,11 +654,12 @@ out:
}
static int restorecon_sb(const char *pathname, const struct stat *sb,
- const struct rest_flags *flags, bool first)
+ const struct rest_flags *flags, bool first, bool *updated_out)
{
char *newcon = NULL;
char *curcon = NULL;
int rc;
+ bool updated = false;
const char *lookup_path = pathname;
if (rootpath) {
@@ -736,7 +741,6 @@ static int restorecon_sb(const char *pathname, const struct stat *sb,
}
if (curcon == NULL || strcmp(curcon, newcon) != 0) {
- bool updated = false;
if (!flags->set_specctx && curcon &&
(is_context_customizable(curcon) > 0)) {
@@ -796,9 +800,14 @@ static int restorecon_sb(const char *pathname, const struct stat *sb,
syslog(LOG_INFO, "labeling %s to %s\n",
pathname, newcon);
}
+
+ /* Note: relabel counting handled by caller */
+
}
out:
+ if (updated_out)
+ *updated_out = updated;
rc = 0;
out1:
freecon(curcon);
@@ -887,6 +896,7 @@ struct rest_state {
bool abort;
int error;
long unsigned skipped_errors;
+ long unsigned relabeled_files;
int saved_errno;
pthread_mutex_t mutex;
};
@@ -1010,8 +1020,9 @@ loop_body:
if (state->parallel)
pthread_mutex_unlock(&state->mutex);
+ bool updated = false;
error = restorecon_sb(ent_path, &ent_st, &state->flags,
- first);
+ first, &updated);
if (state->parallel) {
pthread_mutex_lock(&state->mutex);
@@ -1030,6 +1041,8 @@ loop_body:
state->skipped_errors++;
else
state->error = error;
+ } else if (updated && state->flags.count_relabeled) {
+ state->relabeled_files++;
}
break;
}
@@ -1087,6 +1100,8 @@ static int selinux_restorecon_common(const char *pathname_orig,
SELINUX_RESTORECON_IGNORE_DIGEST) ? true : false;
state.flags.count_errors = (restorecon_flags &
SELINUX_RESTORECON_COUNT_ERRORS) ? true : false;
+ state.flags.count_relabeled = (restorecon_flags &
+ SELINUX_RESTORECON_COUNT_RELABELED) ? true : false;
state.setrestorecondigest = true;
state.head = NULL;
@@ -1094,6 +1109,7 @@ static int selinux_restorecon_common(const char *pathname_orig,
state.abort = false;
state.error = 0;
state.skipped_errors = 0;
+ state.relabeled_files = 0;
state.saved_errno = 0;
struct stat sb;
@@ -1215,7 +1231,11 @@ static int selinux_restorecon_common(const char *pathname_orig,
goto cleanup;
}
- error = restorecon_sb(pathname, &sb, &state.flags, true);
+ bool updated = false;
+ error = restorecon_sb(pathname, &sb, &state.flags, true, &updated);
+ if (updated && state.flags.count_relabeled) {
+ state.relabeled_files++;
+ }
goto cleanup;
}
@@ -1341,6 +1361,7 @@ out:
(void) fts_close(state.fts);
errno = state.saved_errno;
cleanup:
+ relabeled_files = state.relabeled_files;
if (state.flags.add_assoc) {
if (state.flags.verbose)
filespec_eval();
@@ -1618,3 +1639,8 @@ long unsigned selinux_restorecon_get_skipped_errors(void)
{
return skipped_errors;
}
+
+long unsigned selinux_restorecon_get_relabeled_files(void)
+{
+ return relabeled_files;
+}
diff --git a/policycoreutils/setfiles/restore.c b/policycoreutils/setfiles/restore.c
index 2c031ccc..07582e7c 100644
--- a/policycoreutils/setfiles/restore.c
+++ b/policycoreutils/setfiles/restore.c
@@ -43,7 +43,7 @@ void restore_init(struct restore_opts *opts)
opts->syslog_changes | opts->log_matches |
opts->ignore_noent | opts->ignore_mounts |
opts->mass_relabel | opts->conflict_error |
- opts->count_errors;
+ opts->count_errors | opts->count_relabeled;
/* Use setfiles, restorecon and restorecond own handles */
selinux_restorecon_set_sehandle(opts->hnd);
@@ -75,7 +75,7 @@ void restore_finish(void)
}
int process_glob(char *name, struct restore_opts *opts, size_t nthreads,
- long unsigned *skipped_errors)
+ long unsigned *skipped_errors, long unsigned *relabeled_files)
{
glob_t globbuf;
size_t i, len;
@@ -99,8 +99,12 @@ int process_glob(char *name, struct restore_opts *opts, size_t nthreads,
nthreads);
if (rc < 0)
errors = rc;
- else if (opts->restorecon_flags & SELINUX_RESTORECON_COUNT_ERRORS)
- *skipped_errors += selinux_restorecon_get_skipped_errors();
+ else {
+ if (opts->restorecon_flags & SELINUX_RESTORECON_COUNT_ERRORS)
+ *skipped_errors += selinux_restorecon_get_skipped_errors();
+ if (opts->restorecon_flags & SELINUX_RESTORECON_COUNT_RELABELED)
+ *relabeled_files += selinux_restorecon_get_relabeled_files();
+ }
}
globfree(&globbuf);
diff --git a/policycoreutils/setfiles/restore.h b/policycoreutils/setfiles/restore.h
index 95afb960..36f73059 100644
--- a/policycoreutils/setfiles/restore.h
+++ b/policycoreutils/setfiles/restore.h
@@ -37,6 +37,7 @@ struct restore_opts {
unsigned int ignore_mounts;
unsigned int conflict_error;
unsigned int count_errors;
+ unsigned int count_relabeled;
/* restorecon_flags holds | of above for restore_init() */
unsigned int restorecon_flags;
char *rootpath;
@@ -52,7 +53,7 @@ void restore_init(struct restore_opts *opts);
void restore_finish(void);
void add_exclude(const char *directory);
int process_glob(char *name, struct restore_opts *opts, size_t nthreads,
- long unsigned *skipped_errors);
+ long unsigned *skipped_errors, long unsigned *relabeled_files);
extern char **exclude_list;
#endif
diff --git a/policycoreutils/setfiles/restorecon.8 b/policycoreutils/setfiles/restorecon.8
index 77dd0542..66b9c800 100644
--- a/policycoreutils/setfiles/restorecon.8
+++ b/policycoreutils/setfiles/restorecon.8
@@ -153,6 +153,9 @@ display warnings about entries that had no matching files by outputting the
.BR selabel_stats (3)
results.
.TP
+.B \-c
+count and display the number of (would be) relabeled files. The exit code will be set to 0 only if at least one file is relabeled.
+.TP
.B \-0
the separator for the input items is assumed to be the null character
(instead of the white space). The quotes and the backslash characters are
diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c
index 31034316..351940f3 100644
--- a/policycoreutils/setfiles/setfiles.c
+++ b/policycoreutils/setfiles/setfiles.c
@@ -35,8 +35,8 @@ static __attribute__((__noreturn__)) void usage(const char *const name)
{
if (iamrestorecon) {
fprintf(stderr,
- "usage: %s [-iIDFUmnprRv0xT] [-e excludedir] pathname...\n"
- "usage: %s [-iIDFUmnprRv0xT] [-e excludedir] -f filename\n",
+ "usage: %s [-ciIDFUmnprRv0xT] [-e excludedir] pathname...\n"
+ "usage: %s [-ciIDFUmnprRv0xT] [-e excludedir] -f filename\n",
name, name);
} else {
fprintf(stderr,
@@ -146,11 +146,12 @@ int main(int argc, char **argv)
size_t buf_len, nthreads = 1;
const char *base;
int errors = 0;
- const char *ropts = "e:f:hiIDlmno:pqrsvFURW0xT:";
+ const char *ropts = "ce:f:hiIDlmno:pqrsvFURW0xT:";
const char *sopts = "c:de:f:hiIDlmno:pqr:svACEFUR:W0T:";
const char *opts;
union selinux_callback cb;
long unsigned skipped_errors;
+ long unsigned relabeled_files;
/* Initialize variables */
memset(&r_opts, 0, sizeof(r_opts));
@@ -160,6 +161,7 @@ int main(int argc, char **argv)
request_digest = 0;
policyfile = NULL;
skipped_errors = 0;
+ relabeled_files = 0;
if (!argv[0]) {
fprintf(stderr, "Called without required program name!\n");
@@ -223,7 +225,10 @@ int main(int argc, char **argv)
while ((opt = getopt(argc, argv, opts)) > 0) {
switch (opt) {
case 'c':
- {
+ if (iamrestorecon) {
+ r_opts.count_relabeled = SELINUX_RESTORECON_COUNT_RELABELED;
+ break;
+ } else {
FILE *policystream;
policyfile = optarg;
@@ -457,14 +462,14 @@ int main(int argc, char **argv)
if (!strcmp(buf, "/"))
r_opts.mass_relabel = SELINUX_RESTORECON_MASS_RELABEL;
errors |= process_glob(buf, &r_opts, nthreads,
- &skipped_errors) < 0;
+ &skipped_errors, &relabeled_files) < 0;
}
if (strcmp(input_filename, "-") != 0)
fclose(f);
} else {
for (i = optind; i < argc; i++)
errors |= process_glob(argv[i], &r_opts, nthreads,
- &skipped_errors) < 0;
+ &skipped_errors, &relabeled_files) < 0;
}
if (r_opts.mass_relabel && !r_opts.nochange)
@@ -479,5 +484,14 @@ int main(int argc, char **argv)
if (r_opts.progress)
fprintf(stdout, "\n");
+ /* Output relabeled file count if requested */
+ if (r_opts.count_relabeled) {
+ long unsigned relabeled_count = selinux_restorecon_get_relabeled_files();
+ printf("Relabeled %lu files\n", relabeled_count);
+
+ /* Set exit code to 0 if at least one file was relabeled */
+ exit(errors ? -1 : relabeled_count ? 0 : 1);
+ }
+
exit(errors ? -1 : skipped_errors ? 1 : 0);
}
--
2.52.0

View File

@ -1,3 +1,6 @@
* Fri Feb 06 2026 Vit Mojzis <vmojzis@redhat.com> - 3.10-1
- SELinux userspace 3.10 release
* Fri Feb 06 2026 Vit Mojzis <vmojzis@redhat.com> - 3.9-3
- Make `rpm` a weak dependency (bz#2338647)

585
perfinion.gpg Normal file
View File

@ -0,0 +1,585 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
ehEYP6Aum+1xkBkUWGIOytllY/3B9mCUGFZGdk2AvzCsELcEmVaE0p0Wc/YkepeS
w5tAgCZeVNlRZiiXNhdQL/RWE2nBOpAuFMFaE89vq6oRHYZ/mTznnuQazzePKpye
MT9pmFEN1uhAKjbQRzyoWC7ep8LcWgmVix4pXil2eamLDa1T38ILH/fqVTDgjhff
WZFEyWUU2Rm8jokBHAQTAQIABgUCVQV+vQAKCRAi/8zK1QbvrfZiB/4+PtIqYJqH
47bzJz1UyG0pa/xc3lqLjBLJ0QNfELTeK2q/+3lpCGuEb4h9QwtlemTul7vkYAaz
Q3V48JWmEwT4BG9YmJX2dLS7wtGJnFJcwjwJDLFkvoxMPP3mTaC9p1T8JINTBEA8
7DLg633Wsw0g8/dzsmknZ4wOtJCrTuBt6WLTbG95rT1PurqqeNJ1WHJUnq/nWKyQ
TReNviIuJMahAPYRJorLVllABY8NtlfvEbTqRRD0KuxXL41ELFVATKzCAo+qvU7W
Vnq0bW+Fbp28drDr8FZ8hiXUqtzfaXk31WV17o7SrAFDyeA542/u2bzsT1mEyvy5
BaJAMNraXSECiQIzBBABCAAdFiEEoovt4I8XROFgN1FIBsRTZ1V1gAAFAlijFfAA
CgkQBsRTZ1V1gACNdRAAj9tBAB66sGk2aoEUB4rvwbukSj/gdp6do8My9G1Pe3SP
mpU50Q9FcZ42FgFGjnVB+c3vpxz2LhE5PfMZ6Zp66Pjv+69tXmn6Y+dyKor80SOK
ZezkJlPFNTBiuYYQnK5Z3uDPlxTKPkkQxVxx+ImnW65udMMOsOMTmrTJQdCmsaEi
jiN7fQjGSuJURfvDg3PA4LWqyPA24VpayMNqHYT/fekxRCmnFNL2KYRoFEIRk0Hk
4Gy68w3xLlN/zLm4AgQ4m3Iyr1K1cK9hpcNSbB6U1APCg6QmEHA9NqVc91iVhv36
ZVgNCc67g4zjXTi4Rr+bJ2DTo5MnGFI9fZYP84OjAgWYajp6j3kM05Tv7h9kaFaN
pok2l0uxhax1kaNnuFm/Ltmj/rv0oCali50pPTyHey0NQq3RbWYzdcHthqnuoBtS
YpWHvq5VP1hIwDRF7NOU4UqXIK3VKpGfO4xAOFOpOaU1hrPslXJeZK1imxOehiSI
BXvsZ4MMrCgH2gC8ug/51DmNjNnWjNi5Z6abA5SgBfr7jgCUGEaARntR7AX2d638
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
yuYYmf6A1AA7vZ+t
=P1hn
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -1,7 +1,7 @@
%global libauditver 3.0
%global libsepolver 3.9-1
%global libsemanagever 3.9-1
%global libselinuxver 3.9-4
%global libauditver 4.0
%global libsepolver 3.10-1
%global libsemanagever 3.10-1
%global libselinuxver 3.10-1
%global generatorsdir %{_prefix}/lib/systemd/system-generators
@ -10,13 +10,13 @@
Summary: SELinux policy core utilities
Name: policycoreutils
Version: 3.9
Release: 3%{?dist}
Version: 3.10
Release: 1%{?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
Source1: https://github.com/SELinuxProject/selinux/releases/download/%{version}/selinux-%{version}.tar.gz.asc
Source2: https://github.com/bachradsusi.gpg
Source2: https://github.com/perfinion.gpg
Source3: changelog
Source4: macros
URL: https://github.com/SELinuxProject/selinux
@ -37,7 +37,7 @@ Source22: selinux-gui.zip
# wlc --key <apikey> --url https://translate.fedoraproject.org/api/ download selinux/sandbox --output ./
Source23: selinux-sandbox.zip
# https://github.com/fedora-selinux/selinux
# $ git format-patch -N 3.9 -- policycoreutils python gui sandbox dbus semodule-utils restorecond
# $ git format-patch -N 3.10 -- policycoreutils python gui sandbox dbus semodule-utils restorecond
# $ for j in [0-9]*.patch; do printf "Patch%s: %s\n" ${j/-*/} $j; done
# Patch list start
Patch0001: 0001-Don-t-be-verbose-if-you-are-not-on-a-tty.patch
@ -46,10 +46,6 @@ 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
Patch0009: 0009-restorecon-Add-option-to-count-relabeled-files.patch
# Patch0009 ^^^ needs to also contain diff for libselinux because of updated header files
# Patch list end
# gen_changelog

View File

@ -2,5 +2,5 @@ SHA512 (selinux-policycoreutils.zip) = 0df9dc274e0d1a2e4e2467f95a18a5bf7b6de2428
SHA512 (selinux-python.zip) = 35d209f8bcff498f66465499fcc4cef0780781276a4ba060b2d1d56eed1dd72d253f6b0eae5f679d46cf426b967a7aadac909363513be5d483c95a31249eacdd
SHA512 (selinux-sandbox.zip) = ecbc0c8280eb6c013b039a2e63ee5a361cd84807613962a012ac0a98092357e9809bea23c3c71bd8ae4745b1dd12a4fce43db5e1cab31614f386a2a8db88b733
SHA512 (selinux-gui.zip) = 3ae41eba5dd6d34e10dfdb97f4194d170ace2f3044e984077db7d26d05bdaad86625e48e5694e3e8680487ad99a50861d4bea30c4bf08e2820e3b7a8671270c7
SHA512 (selinux-3.9.tar.gz) = ccfe9c8907ef50e35cda1e8282a4e02e8d2e1749dabde856343f236724214c89d0bcd4e799f383961b990c5fb9a6b0191880a478a8930af447951c8b36689720
SHA512 (selinux-3.9.tar.gz.asc) = 598498e3919c72e1b7e6db85250ac7b1ff26e33598fb94c29ee74569dddee407fca73961d9fbb245ecf5ff5a7ee0eaa83031f79b7f0b2d89661119d45bbf5954
SHA512 (selinux-3.10.tar.gz) = 40ada85709ad23c368579bc661661ac77f4ada6d9a65243bc25de8e46202baed264d1b49de1765d5dd21ebc8d94d872b86d2b0e7b56a7269f1942d609ff7278e
SHA512 (selinux-3.10.tar.gz.asc) = 5efaecb97be2da435c7ece88e213dd753a4c6ee6f6a2726f25b82b0e30c77a5136efb593fb9590c0395f0c63e9536abf407dcec95b3d62027defbeafaa5d4b91