libselinux-3.9-4

- restorecon: Add option to count relabeled files

Resolves: RHEL-144056
This commit is contained in:
Vit Mojzis 2026-01-26 16:24:19 +01:00
parent 9666ff6d92
commit 8d6cb98afe
3 changed files with 204 additions and 1 deletions

View File

@ -0,0 +1,199 @@
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 ++++++++++++++++++++++---
3 files changed, 50 insertions(+), 4 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;
+}
--
2.52.0

View File

@ -1,3 +1,6 @@
* Mon Jan 26 2026 Vit Mojzis <vmojzis@redhat.com> - 3.9-4
- restorecon: Add option to count relabeled files (RHEL-144056)
* Mon Dec 15 2025 Veronika Syncakova <vsyncako@redhat.com> - 3.9-3
- Rebuild to accomodate changes in swig (RHEL-118812)

View File

@ -4,7 +4,7 @@
Summary: SELinux library and simple utilities
Name: libselinux
Version: 3.9
Release: 3%{?dist}
Release: 4%{?dist}
License: LicenseRef-Fedora-Public-Domain
# https://github.com/SELinuxProject/selinux/wiki/Releases
Source0: https://github.com/SELinuxProject/selinux/releases/download/%{version}/libselinux-%{version}.tar.gz
@ -21,6 +21,7 @@ Url: https://github.com/SELinuxProject/selinux/wiki
# Patch list start
Patch0001: 0001-Use-SHA-2-instead-of-SHA-1.patch
Patch0002: 0002-libselinux-Ignore-files-removed-during-relabeling.patch
Patch0003: 0003-restorecon-Add-option-to-count-relabeled-files.patch
# Patch list end
BuildRequires: gcc make
BuildRequires: ruby-devel ruby libsepol-static >= %{libsepolver} swig pcre2-devel