All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH for-3.5 0/5] selinux_restorecon(3), setfiles(8): skip relabeling errors
@ 2022-04-28  6:53 Laszlo Ersek
  2022-04-28  6:53 ` [PATCH for-3.5 1/5] setfiles: fix up inconsistent indentation Laszlo Ersek
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Laszlo Ersek @ 2022-04-28  6:53 UTC (permalink / raw)
  To: SELinux List, Laszlo Ersek; +Cc: Richard W.M. Jones, Petr Lautrbach

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1794518

The first three patches in the series are cleanups.

The fourth patch introduces a new feature (and API) to libselinux, and
the fifth patch exposes the feature through a new setfiles(8) command
line option.

In libguestfs, we invoke setfiles(8) on masses of directory trees (in a
large amount of virtual machines). We don't care if relabeling fails on
a few individual files, but we still want to catch fatal errors.
Currently these error conditions are impossible to tell apart, because
selinux_restorecon[_parallel()], even though it is capable of continuing
through relabeling errors, ultimately reports even the case of *only*
relabeling errors, with return value (-1). Setfiles(8) then has no
choice but to exit with status 255 in this case as well.

The fourth patch introduces a new selinux_restorecon[_parallel()] flag,
namely SELINUX_RESTORECON_COUNT_ERRORS, which counts, but otherwise
ignores, relabeling errors encountered during the file tree walk. In
case the function succeeds, the skipped error count can be fetched with
a new API, selinux_restorecon_get_skipped_errors(). This relies on
static library data, which is inspired by existent APIs such as
selinux_restorecon_set_sehandle(3) and
selinux_restorecon_set_exclude_list(3) -- those do the same (albeit
before calling selinux_restorecon[_parallel()], not after).

The fifth patch wires the new flag to the new setfiles(8) option "-C".

Please CC me on all replies to the series; I'm not subscribed to the
SELinux mailing list. ("CONTRIBUTING.md" does not say that subscribing
is a requirement.)

Cc: "Richard W.M. Jones" <rjones@redhat.com>
Cc: Petr Lautrbach <plautrba@redhat.com>

Thanks,
Laszlo

Laszlo Ersek (5):
  setfiles: fix up inconsistent indentation
  setfiles: remove useless assignment and comment (after RHBZ#1926386)
  setfiles: remove useless "iamrestorecon" checks in option parsing
  selinux_restorecon: introduce SELINUX_RESTORECON_COUNT_ERRORS
  setfiles: introduce the -C option for distinguishing file tree walk
    errors

 libselinux/include/selinux/restorecon.h                     | 15 ++++++++
 libselinux/man/man3/selinux_restorecon.3                    | 22 +++++++++++-
 libselinux/man/man3/selinux_restorecon_get_skipped_errors.3 | 28 +++++++++++++++
 libselinux/src/libselinux.map                               |  5 +++
 libselinux/src/selinux_restorecon.c                         | 34 +++++++++++++++---
 policycoreutils/setfiles/restore.c                          |  8 +++--
 policycoreutils/setfiles/restore.h                          |  4 ++-
 policycoreutils/setfiles/setfiles.8                         | 22 ++++++++++++
 policycoreutils/setfiles/setfiles.c                         | 36 +++++++++-----------
 9 files changed, 145 insertions(+), 29 deletions(-)
 create mode 100644 libselinux/man/man3/selinux_restorecon_get_skipped_errors.3


base-commit: 2a167d1156578fc29541f6fb60af65452f431aae
-- 
2.19.1.3.g30247aa5d201


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH for-3.5 1/5] setfiles: fix up inconsistent indentation
  2022-04-28  6:53 [PATCH for-3.5 0/5] selinux_restorecon(3), setfiles(8): skip relabeling errors Laszlo Ersek
@ 2022-04-28  6:53 ` Laszlo Ersek
  2022-04-28  6:53 ` [PATCH for-3.5 2/5] setfiles: remove useless assignment and comment (after RHBZ#1926386) Laszlo Ersek
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Laszlo Ersek @ 2022-04-28  6:53 UTC (permalink / raw)
  To: SELinux List, Laszlo Ersek; +Cc: Richard W.M. Jones, Petr Lautrbach

Commit 7ad84e7c8d4f ("Add restorecon -x option to not cross FS
boundaries", 2020-06-18) used spaces vs. TABs inconsistently; run
"unexpand" on the affected lines to make the indentation conform to the
rest of the source code.

Cc: "Richard W.M. Jones" <rjones@redhat.com>
Cc: Petr Lautrbach <plautrba@redhat.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1794518
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
 policycoreutils/setfiles/setfiles.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c
index ab7016aca9a6..be88be5d5497 100644
--- a/policycoreutils/setfiles/setfiles.c
+++ b/policycoreutils/setfiles/setfiles.c
@@ -368,13 +368,13 @@ int main(int argc, char **argv)
 		case '0':
 			null_terminated = 1;
 			break;
-                case 'x':
-                        if (iamrestorecon) {
+		case 'x':
+			if (iamrestorecon) {
 				r_opts.xdev = SELINUX_RESTORECON_XDEV;
-                        } else {
+			} else {
 				usage(argv[0]);
-                        }
-                        break;
+			}
+			break;
 		case 'T':
 			nthreads = strtoull(optarg, &endptr, 10);
 			if (*optarg == '\0' || *endptr != '\0')
-- 
2.19.1.3.g30247aa5d201



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH for-3.5 2/5] setfiles: remove useless assignment and comment (after RHBZ#1926386)
  2022-04-28  6:53 [PATCH for-3.5 0/5] selinux_restorecon(3), setfiles(8): skip relabeling errors Laszlo Ersek
  2022-04-28  6:53 ` [PATCH for-3.5 1/5] setfiles: fix up inconsistent indentation Laszlo Ersek
@ 2022-04-28  6:53 ` Laszlo Ersek
  2022-04-28  6:53 ` [PATCH for-3.5 3/5] setfiles: remove useless "iamrestorecon" checks in option parsing Laszlo Ersek
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Laszlo Ersek @ 2022-04-28  6:53 UTC (permalink / raw)
  To: SELinux List, Laszlo Ersek; +Cc: Richard W.M. Jones, Petr Lautrbach

Commit 9207823c8ff0 ("setfiles: Do not abort on labeling error",
2021-02-01) hoisted the zeroing of "r_opts.abort_on_error" above the
branching on "setfiles vs. restorecon". Clean up two aspects:

- "r_opts" is altogether zeroed a bit higher up, so remove the explicit
  zero-assignment;

- neither "setfiles" nor "restorecon" aborts on errors during the file
  tree walk now, so remove the comment "Do not abort on errors during the
  file tree walk" from the "restorecon" branch as well.

Cc: "Richard W.M. Jones" <rjones@redhat.com>
Cc: Petr Lautrbach <plautrba@redhat.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1794518
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
 policycoreutils/setfiles/setfiles.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c
index be88be5d5497..cf504618d38f 100644
--- a/policycoreutils/setfiles/setfiles.c
+++ b/policycoreutils/setfiles/setfiles.c
@@ -162,7 +162,6 @@ int main(int argc, char **argv)
 	request_digest = 0;
 	policyfile = NULL;
 
-	r_opts.abort_on_error = 0;
 	if (!argv[0]) {
 		fprintf(stderr, "Called without required program name!\n");
 		exit(-1);
@@ -197,7 +196,6 @@ int main(int argc, char **argv)
 		 * restorecon:
 		 * No recursive descent unless -r/-R,
 		 * Expands paths via realpath,
-		 * Do not abort on errors during the file tree walk,
 		 * Do not try to track inode associations for conflict detection,
 		 * Follows mounts,
 		 * Does lazy validation of contexts upon use.
-- 
2.19.1.3.g30247aa5d201



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH for-3.5 3/5] setfiles: remove useless "iamrestorecon" checks in option parsing
  2022-04-28  6:53 [PATCH for-3.5 0/5] selinux_restorecon(3), setfiles(8): skip relabeling errors Laszlo Ersek
  2022-04-28  6:53 ` [PATCH for-3.5 1/5] setfiles: fix up inconsistent indentation Laszlo Ersek
  2022-04-28  6:53 ` [PATCH for-3.5 2/5] setfiles: remove useless assignment and comment (after RHBZ#1926386) Laszlo Ersek
@ 2022-04-28  6:53 ` Laszlo Ersek
  2022-04-28 16:07   ` Daniel Burgener
  2022-04-28  6:53 ` [PATCH for-3.5 4/5] selinux_restorecon: introduce SELINUX_RESTORECON_COUNT_ERRORS Laszlo Ersek
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Laszlo Ersek @ 2022-04-28  6:53 UTC (permalink / raw)
  To: SELinux List, Laszlo Ersek; +Cc: Richard W.M. Jones, Petr Lautrbach

Commit 219eea83cea9 ("policycoreutils: setfiles/restorecon: fix -r/-R
option", 2015-04-16) split the option strings between "setfiles" and
"restorecon". Since that commit, an "iamrestorecon" check has only been
necessary for an option that is (a) accepted by both "setfiles" and
"restorecon", but (b) behaves differently between "setfiles" and
"restorecon". Currently, the only such options are "-r" and "-R". Remove
the "iamrestorecon" checks from the "setfiles"-only "-c" and "-d" options,
and from the "restorecon"-only "-x" option.

Cc: "Richard W.M. Jones" <rjones@redhat.com>
Cc: Petr Lautrbach <plautrba@redhat.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1794518
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
 policycoreutils/setfiles/setfiles.c | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c
index cf504618d38f..aeec1fdcc2ab 100644
--- a/policycoreutils/setfiles/setfiles.c
+++ b/policycoreutils/setfiles/setfiles.c
@@ -227,9 +227,6 @@ int main(int argc, char **argv)
 			{
 				FILE *policystream;
 
-				if (iamrestorecon)
-					usage(argv[0]);
-
 				policyfile = optarg;
 
 				policystream = fopen(policyfile, "r");
@@ -267,8 +264,6 @@ int main(int argc, char **argv)
 			input_filename = optarg;
 			break;
 		case 'd':
-			if (iamrestorecon)
-				usage(argv[0]);
 			r_opts.debug = 1;
 			r_opts.log_matches =
 					   SELINUX_RESTORECON_LOG_MATCHES;
@@ -367,11 +362,7 @@ int main(int argc, char **argv)
 			null_terminated = 1;
 			break;
 		case 'x':
-			if (iamrestorecon) {
-				r_opts.xdev = SELINUX_RESTORECON_XDEV;
-			} else {
-				usage(argv[0]);
-			}
+			r_opts.xdev = SELINUX_RESTORECON_XDEV;
 			break;
 		case 'T':
 			nthreads = strtoull(optarg, &endptr, 10);
-- 
2.19.1.3.g30247aa5d201



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH for-3.5 4/5] selinux_restorecon: introduce SELINUX_RESTORECON_COUNT_ERRORS
  2022-04-28  6:53 [PATCH for-3.5 0/5] selinux_restorecon(3), setfiles(8): skip relabeling errors Laszlo Ersek
                   ` (2 preceding siblings ...)
  2022-04-28  6:53 ` [PATCH for-3.5 3/5] setfiles: remove useless "iamrestorecon" checks in option parsing Laszlo Ersek
@ 2022-04-28  6:53 ` Laszlo Ersek
  2022-04-29  8:13   ` Petr Lautrbach
  2022-04-28  6:53 ` [PATCH for-3.5 5/5] setfiles: introduce the -C option for distinguishing file tree walk errors Laszlo Ersek
  2022-04-28  9:22 ` [PATCH for-3.5 0/5] selinux_restorecon(3), setfiles(8): skip relabeling errors Richard W.M. Jones
  5 siblings, 1 reply; 11+ messages in thread
From: Laszlo Ersek @ 2022-04-28  6:53 UTC (permalink / raw)
  To: SELinux List, Laszlo Ersek; +Cc: Richard W.M. Jones, Petr Lautrbach

Currently, if the SELINUX_RESTORECON_ABORT_ON_ERROR flag is clear, then
selinux_restorecon[_parallel]() does not abort the file tree walk upon an
error, but the function itself fails the same, with the same (-1) return
value. This in turn is reported by the setfiles(8) utility to its parent
process with the same exit code (255).

In libguestfs we want to proceed after setfiles(8) fails *at most* with
such errors that occur during the file tree walk. We need setfiles(8) to
exit with a distinct exit status in that situation.

For this, introduce the SELINUX_RESTORECON_COUNT_ERRORS flag, and the
corresponding selinux_restorecon_get_skipped_errors() function, for
selinux_restorecon[_parallel]() to count, but otherwise ignore, errors
during the file tree walk. When no other kind of error occurs, the
relabeling functions will return zero, and the caller can fetch the number
of errors ignored during the file tree walk with
selinux_restorecon_get_skipped_errors().

Importantly, when at least one such error is skipped, we don't write
partial match digests for subdirectories, as any masked error means that
any subdirectory may not have been completely relabeled.

Cc: "Richard W.M. Jones" <rjones@redhat.com>
Cc: Petr Lautrbach <plautrba@redhat.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1794518
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
 libselinux/include/selinux/restorecon.h                     | 15 +++++++++
 libselinux/src/selinux_restorecon.c                         | 34 +++++++++++++++++---
 libselinux/man/man3/selinux_restorecon.3                    | 22 ++++++++++++-
 libselinux/man/man3/selinux_restorecon_get_skipped_errors.3 | 28 ++++++++++++++++
 libselinux/src/libselinux.map                               |  5 +++
 5 files changed, 98 insertions(+), 6 deletions(-)

diff --git a/libselinux/include/selinux/restorecon.h b/libselinux/include/selinux/restorecon.h
index 1821a3dc596c..b10fe684eff9 100644
--- a/libselinux/include/selinux/restorecon.h
+++ b/libselinux/include/selinux/restorecon.h
@@ -121,6 +121,11 @@ extern int selinux_restorecon_parallel(const char *pathname,
  */
 #define SELINUX_RESTORECON_CONFLICT_ERROR		0x10000
 
+/*
+ * Count, but otherwise ignore, errors during the file tree walk.
+ */
+#define SELINUX_RESTORECON_COUNT_ERRORS			0x20000
+
 /**
  * selinux_restorecon_set_sehandle - Set the global fc handle.
  * @hndl: specifies handle to set as the global fc handle.
@@ -205,6 +210,16 @@ extern int selinux_restorecon_xattr(const char *pathname,
 /* Do not read /proc/mounts. */
 #define SELINUX_RESTORECON_XATTR_IGNORE_MOUNTS			0x0008
 
+/* selinux_restorecon_get_skipped_errors - Get the number of errors ignored
+ * during re-labeling.
+ *
+ * If SELINUX_RESTORECON_COUNT_ERRORS was passed to selinux_restorecon(3) or
+ * selinux_restorecon_parallel(3), and that function returned successfully
+ * (i.e., with a zero return value), then this function returns the number of
+ * errors ignored during the file tree walk.
+ */
+extern long unsigned selinux_restorecon_get_skipped_errors(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libselinux/src/selinux_restorecon.c b/libselinux/src/selinux_restorecon.c
index 72f4fb462e34..e61929120a74 100644
--- a/libselinux/src/selinux_restorecon.c
+++ b/libselinux/src/selinux_restorecon.c
@@ -66,6 +66,9 @@ static pthread_mutex_t progress_mutex = PTHREAD_MUTEX_INITIALIZER;
 static struct dir_xattr *dir_xattr_list;
 static struct dir_xattr *dir_xattr_last;
 
+/* Number of errors ignored during the file tree walk. */
+static long unsigned skipped_errors;
+
 /* restorecon_flags for passing to restorecon_sb() */
 struct rest_flags {
 	bool nochange;
@@ -83,6 +86,7 @@ struct rest_flags {
 	bool ignore_noent;
 	bool warnonnomatch;
 	bool conflicterror;
+	bool count_errors;
 };
 
 static void restorecon_init(void)
@@ -827,6 +831,7 @@ struct rest_state {
 	struct dir_hash_node *head, *current;
 	bool abort;
 	int error;
+	long unsigned skipped_errors;
 	int saved_errno;
 	pthread_mutex_t mutex;
 };
@@ -949,11 +954,17 @@ loop_body:
 					goto unlock;
 			}
 
-			state->error |= error;
 			first = false;
-			if (error && state->flags.abort_on_error) {
-				state->abort = true;
-				goto finish;
+			if (error) {
+				if (state->flags.abort_on_error) {
+					state->error = error;
+					state->abort = true;
+					goto finish;
+				}
+				if (state->flags.count_errors)
+					state->skipped_errors++;
+				else
+					state->error = error;
 			}
 			break;
 		}
@@ -1007,12 +1018,15 @@ static int selinux_restorecon_common(const char *pathname_orig,
 		   SELINUX_RESTORECON_IGNORE_MOUNTS) ? true : false;
 	state.ignore_digest = (restorecon_flags &
 		    SELINUX_RESTORECON_IGNORE_DIGEST) ? true : false;
+	state.flags.count_errors = (restorecon_flags &
+		    SELINUX_RESTORECON_COUNT_ERRORS) ? true : false;
 	state.setrestorecondigest = true;
 
 	state.head = NULL;
 	state.current = NULL;
 	state.abort = false;
 	state.error = 0;
+	state.skipped_errors = 0;
 	state.saved_errno = 0;
 
 	struct stat sb;
@@ -1225,8 +1239,11 @@ static int selinux_restorecon_common(const char *pathname_orig,
 	/*
 	 * Labeling successful. Write partial match digests for subdirectories.
 	 * TODO: Write digest upon FTS_DP if no error occurs in its descents.
+	 * Note: we can't ignore errors here that we've masked due to
+	 * SELINUX_RESTORECON_COUNT_ERRORS.
 	 */
-	if (state.setrestorecondigest && !state.flags.nochange && !error) {
+	if (state.setrestorecondigest && !state.flags.nochange && !error &&
+	    state.skipped_errors == 0) {
 		current = state.head;
 		while (current != NULL) {
 			if (setxattr(current->path,
@@ -1241,6 +1258,8 @@ static int selinux_restorecon_common(const char *pathname_orig,
 		}
 	}
 
+	skipped_errors = state.skipped_errors;
+
 out:
 	if (state.flags.progress && state.flags.mass_relabel)
 		fprintf(stdout, "\r%s 100.0%%\n", pathname);
@@ -1520,3 +1539,8 @@ cleanup:
 	}
 	return -1;
 }
+
+long unsigned selinux_restorecon_get_skipped_errors(void)
+{
+	return skipped_errors;
+}
diff --git a/libselinux/man/man3/selinux_restorecon.3 b/libselinux/man/man3/selinux_restorecon.3
index 334d2930bb4f..218aaf6d2ae5 100644
--- a/libselinux/man/man3/selinux_restorecon.3
+++ b/libselinux/man/man3/selinux_restorecon.3
@@ -78,7 +78,10 @@ specfile entries SHA1 digest. The specfile entries digest will be written to the
 .IR security.sehash
 extended attribute once relabeling has been completed successfully provided the
 .B SELINUX_RESTORECON_NOCHANGE
-flag has not been set.
+flag has not been set, and no errors have been skipped during the file tree walk
+due to the
+.B SELINUX_RESTORECON_COUNT_ERRORS
+flag.
 .sp
 .B SELINUX_RESTORECON_NOCHANGE
 don't change any file labels (passive check) or update the digest in the
@@ -164,6 +167,21 @@ on a directory below this.
 .B SELINUX_RESTORECON_CONFLICT_ERROR
 to treat conflicting specifications, such as where two hardlinks for the
 same inode have different contexts, as errors.
+.sp
+.B SELINUX_RESTORECON_COUNT_ERRORS
+Count, but otherwise ignore, errors during the file tree walk. Only makes a
+difference if the
+.B SELINUX_RESTORECON_ABORT_ON_ERROR
+flag is clear. Call
+.BR selinux_restorecon_get_skipped_errors (3)
+for fetching the ignored (skipped) error count after
+.BR selinux_restorecon (3)
+or
+.BR selinux_restorecon_parallel (3)
+completes with success. In case any errors were skipped during the file tree
+walk, the specfile entries SHA1 digest will not have been written to the
+.IR security.sehash
+extended attribute.
 .RE
 .sp
 The behavior regarding the checking and updating of the SHA1 digest described
@@ -279,6 +297,8 @@ option.
 .br
 .BR selinux_restorecon_default_handle (3),
 .br
+.BR selinux_restorecon_get_skipped_errors (3),
+.br
 .BR selinux_restorecon_set_exclude_list (3),
 .br
 .BR selinux_restorecon_set_alt_rootpath (3),
diff --git a/libselinux/man/man3/selinux_restorecon_get_skipped_errors.3 b/libselinux/man/man3/selinux_restorecon_get_skipped_errors.3
new file mode 100644
index 000000000000..d1757b7612ab
--- /dev/null
+++ b/libselinux/man/man3/selinux_restorecon_get_skipped_errors.3
@@ -0,0 +1,28 @@
+.TH "selinux_restorecon_get_skipped_errors" "3" "27 Apr 2022" "Security Enhanced Linux" "SELinux API documentation"
+
+.SH "NAME"
+selinux_restorecon_get_skipped_errors \- get the number of errors ignored by
+.BR selinux_restorecon (3)
+or
+.BR selinux_restorecon_parallel (3)
+during the file tree walk
+.
+.SH "SYNOPSIS"
+.B #include <selinux/restorecon.h>
+.sp
+.BI "long unsigned selinux_restorecon_get_skipped_errors(void);"
+.in +\w'long unsigned selinux_restorecon_get_skipped_errors('u
+.
+.SH "DESCRIPTION"
+If
+.B SELINUX_RESTORECON_COUNT_ERRORS
+was passed to
+.BR selinux_restorecon (3)
+or
+.BR selinux_restorecon_parallel (3)
+and that function returned successfully (i.e., with a zero return value), then
+.BR selinux_restorecon_get_skipped_errors ()
+returns the number of errors ignored during the file tree walk.
+.
+.SH "SEE ALSO"
+.BR selinux_restorecon (3)
diff --git a/libselinux/src/libselinux.map b/libselinux/src/libselinux.map
index 4acf1caacb55..43631f0965fe 100644
--- a/libselinux/src/libselinux.map
+++ b/libselinux/src/libselinux.map
@@ -245,3 +245,8 @@ LIBSELINUX_3.4 {
   global:
     selinux_restorecon_parallel;
 } LIBSELINUX_1.0;
+
+LIBSELINUX_3.5 {
+  global:
+    selinux_restorecon_get_skipped_errors;
+} LIBSELINUX_3.4;
-- 
2.19.1.3.g30247aa5d201



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH for-3.5 5/5] setfiles: introduce the -C option for distinguishing file tree walk errors
  2022-04-28  6:53 [PATCH for-3.5 0/5] selinux_restorecon(3), setfiles(8): skip relabeling errors Laszlo Ersek
                   ` (3 preceding siblings ...)
  2022-04-28  6:53 ` [PATCH for-3.5 4/5] selinux_restorecon: introduce SELINUX_RESTORECON_COUNT_ERRORS Laszlo Ersek
@ 2022-04-28  6:53 ` Laszlo Ersek
  2022-04-28  9:22 ` [PATCH for-3.5 0/5] selinux_restorecon(3), setfiles(8): skip relabeling errors Richard W.M. Jones
  5 siblings, 0 replies; 11+ messages in thread
From: Laszlo Ersek @ 2022-04-28  6:53 UTC (permalink / raw)
  To: SELinux List, Laszlo Ersek; +Cc: Richard W.M. Jones, Petr Lautrbach

setfiles(8) exits with status 255 if it encounters any error. Introduce
the "-C" option: if the only errors that setfiles(8) encounters are
labeling errors seen during the file tree walk(s), then let setfiles(8)
exit with status 1.

Cc: "Richard W.M. Jones" <rjones@redhat.com>
Cc: Petr Lautrbach <plautrba@redhat.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1794518
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
 policycoreutils/setfiles/restore.h  |  4 +++-
 policycoreutils/setfiles/restore.c  |  8 +++++--
 policycoreutils/setfiles/setfiles.c | 19 +++++++++++------
 policycoreutils/setfiles/setfiles.8 | 22 ++++++++++++++++++++
 4 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/policycoreutils/setfiles/restore.h b/policycoreutils/setfiles/restore.h
index bb35a1db9e34..a5af81fe3bb4 100644
--- a/policycoreutils/setfiles/restore.h
+++ b/policycoreutils/setfiles/restore.h
@@ -35,6 +35,7 @@ struct restore_opts {
 	unsigned int ignore_noent;
 	unsigned int ignore_mounts;
 	unsigned int conflict_error;
+	unsigned int count_errors;
 	/* restorecon_flags holds | of above for restore_init() */
 	unsigned int restorecon_flags;
 	char *rootpath;
@@ -49,7 +50,8 @@ struct restore_opts {
 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);
+int process_glob(char *name, struct restore_opts *opts, size_t nthreads,
+		 long unsigned *skipped_errors);
 extern char **exclude_list;
 
 #endif
diff --git a/policycoreutils/setfiles/restore.c b/policycoreutils/setfiles/restore.c
index e9ae33ad039a..6131f46a7523 100644
--- a/policycoreutils/setfiles/restore.c
+++ b/policycoreutils/setfiles/restore.c
@@ -41,7 +41,8 @@ void restore_init(struct restore_opts *opts)
 			   opts->xdev | opts->abort_on_error |
 			   opts->syslog_changes | opts->log_matches |
 			   opts->ignore_noent | opts->ignore_mounts |
-			   opts->mass_relabel | opts->conflict_error;
+			   opts->mass_relabel | opts->conflict_error |
+			   opts->count_errors;
 
 	/* Use setfiles, restorecon and restorecond own handles */
 	selinux_restorecon_set_sehandle(opts->hnd);
@@ -72,7 +73,8 @@ void restore_finish(void)
 	}
 }
 
-int process_glob(char *name, struct restore_opts *opts, size_t nthreads)
+int process_glob(char *name, struct restore_opts *opts, size_t nthreads,
+		 long unsigned *skipped_errors)
 {
 	glob_t globbuf;
 	size_t i = 0;
@@ -96,6 +98,8 @@ 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();
 	}
 
 	globfree(&globbuf);
diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c
index aeec1fdcc2ab..4dd0d0dc3835 100644
--- a/policycoreutils/setfiles/setfiles.c
+++ b/policycoreutils/setfiles/setfiles.c
@@ -40,8 +40,8 @@ static __attribute__((__noreturn__)) void usage(const char *const name)
 			name, name);
 	} else {
 		fprintf(stderr,
-			"usage:  %s [-diIDlmnpqvEFWT] [-e excludedir] [-r alt_root_path] [-c policyfile] spec_file pathname...\n"
-			"usage:  %s [-diIDlmnpqvEFWT] [-e excludedir] [-r alt_root_path] [-c policyfile] spec_file -f filename\n"
+			"usage:  %s [-diIDlmnpqvCEFWT] [-e excludedir] [-r alt_root_path] [-c policyfile] spec_file pathname...\n"
+			"usage:  %s [-diIDlmnpqvCEFWT] [-e excludedir] [-r alt_root_path] [-c policyfile] spec_file -f filename\n"
 			"usage:  %s -s [-diIDlmnpqvFWT] spec_file\n",
 			name, name, name);
 	}
@@ -150,9 +150,10 @@ int main(int argc, char **argv)
 	const char *base;
 	int errors = 0;
 	const char *ropts = "e:f:hiIDlmno:pqrsvFRW0xT:";
-	const char *sopts = "c:de:f:hiIDlmno:pqr:svEFR:W0T:";
+	const char *sopts = "c:de:f:hiIDlmno:pqr:svCEFR:W0T:";
 	const char *opts;
 	union selinux_callback cb;
+	long unsigned skipped_errors;
 
 	/* Initialize variables */
 	memset(&r_opts, 0, sizeof(r_opts));
@@ -161,6 +162,7 @@ int main(int argc, char **argv)
 	warn_no_match = 0;
 	request_digest = 0;
 	policyfile = NULL;
+	skipped_errors = 0;
 
 	if (!argv[0]) {
 		fprintf(stderr, "Called without required program name!\n");
@@ -288,6 +290,9 @@ int main(int argc, char **argv)
 			r_opts.syslog_changes =
 					   SELINUX_RESTORECON_SYSLOG_CHANGES;
 			break;
+		case 'C':
+			r_opts.count_errors = SELINUX_RESTORECON_COUNT_ERRORS;
+			break;
 		case 'E':
 			r_opts.conflict_error =
 					   SELINUX_RESTORECON_CONFLICT_ERROR;
@@ -447,13 +452,15 @@ int main(int argc, char **argv)
 			buf[len - 1] = 0;
 			if (!strcmp(buf, "/"))
 				r_opts.mass_relabel = SELINUX_RESTORECON_MASS_RELABEL;
-			errors |= process_glob(buf, &r_opts, nthreads) < 0;
+			errors |= process_glob(buf, &r_opts, nthreads,
+					       &skipped_errors) < 0;
 		}
 		if (strcmp(input_filename, "-") != 0)
 			fclose(f);
 	} else {
 		for (i = optind; i < argc; i++)
-			errors |= process_glob(argv[i], &r_opts, nthreads) < 0;
+			errors |= process_glob(argv[i], &r_opts, nthreads,
+					       &skipped_errors) < 0;
 	}
 
 	maybe_audit_mass_relabel(r_opts.mass_relabel, errors);
@@ -467,5 +474,5 @@ int main(int argc, char **argv)
 	if (r_opts.progress)
 		fprintf(stdout, "\n");
 
-	exit(errors ? -1 : 0);
+	exit(errors ? -1 : skipped_errors ? 1 : 0);
 }
diff --git a/policycoreutils/setfiles/setfiles.8 b/policycoreutils/setfiles/setfiles.8
index 19b59a2cc90d..bf26e161a71d 100644
--- a/policycoreutils/setfiles/setfiles.8
+++ b/policycoreutils/setfiles/setfiles.8
@@ -6,6 +6,7 @@ setfiles \- set SELinux file security contexts.
 .B setfiles
 .RB [ \-c
 .IR policy ]
+.RB [ \-C ]
 .RB [ \-d ]
 .RB [ \-l ]
 .RB [ \-m ]
@@ -58,6 +59,13 @@ option will force a replacement of the entire context.
 .B \-c
 check the validity of the contexts against the specified binary policy.
 .TP
+.B \-C
+If only relabeling errors are encountered during the file tree walks,
+exit with status
+.B 1
+rather than
+.BR 255 .
+.TP
 .B \-d
 show what specification matched each file.
 .TP
@@ -219,6 +227,20 @@ or the
 .B \-s
 option is used.
 
+.SH "EXIT STATUS"
+.B setfiles
+exits with status
+.B 0
+if it encounters no errors. Fatal errors result in status
+.BR 255 .
+Labeling errors encountered during file tree walk(s) result in status
+.B 1
+if the
+.B -C
+option is specified and no other kind of error is encountered, and in status
+.B 255
+otherwise.
+
 .SH "NOTES"
 .IP "1." 4
 .B setfiles
-- 
2.19.1.3.g30247aa5d201


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH for-3.5 0/5] selinux_restorecon(3), setfiles(8): skip relabeling errors
  2022-04-28  6:53 [PATCH for-3.5 0/5] selinux_restorecon(3), setfiles(8): skip relabeling errors Laszlo Ersek
                   ` (4 preceding siblings ...)
  2022-04-28  6:53 ` [PATCH for-3.5 5/5] setfiles: introduce the -C option for distinguishing file tree walk errors Laszlo Ersek
@ 2022-04-28  9:22 ` Richard W.M. Jones
  2022-04-28  9:40   ` Laszlo Ersek
  5 siblings, 1 reply; 11+ messages in thread
From: Richard W.M. Jones @ 2022-04-28  9:22 UTC (permalink / raw)
  To: Laszlo Ersek; +Cc: SELinux List, Petr Lautrbach


A couple of comments:

I'm not clear from the patch series what the difference is between an
error which ignored (and counted) and an error that would actually
stop setfiles immediately.  With setfiles -C, will all errors now be
counted and cause setfiles to exit with 1, or will some errors still
be fatal (exit with 255)?

Why on earth is setfiles originally calling exit(-1) at all?!  I
didn't even know that was allowed.  I wrote a test program and this
does indeed cause the exit status to be 255 (because the status is
&-ed with 0xff).  Never seen a program before calling exit(-1).

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
nbdkit - Flexible, fast NBD server with plugins
https://gitlab.com/nbdkit/nbdkit


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH for-3.5 0/5] selinux_restorecon(3), setfiles(8): skip relabeling errors
  2022-04-28  9:22 ` [PATCH for-3.5 0/5] selinux_restorecon(3), setfiles(8): skip relabeling errors Richard W.M. Jones
@ 2022-04-28  9:40   ` Laszlo Ersek
  0 siblings, 0 replies; 11+ messages in thread
From: Laszlo Ersek @ 2022-04-28  9:40 UTC (permalink / raw)
  To: Richard W.M. Jones; +Cc: SELinux List, Petr Lautrbach

On 04/28/22 11:22, Richard W.M. Jones wrote:
> 
> A couple of comments:
> 
> I'm not clear from the patch series what the difference is between an
> error which ignored (and counted) and an error that would actually
> stop setfiles immediately.

The difference is: with the new flag, we count and ignore exactly those
errors that would abort the processing (the file tree walk) in case
SELINUX_RESTORECON_ABORT_ON_ERROR were specified.

This is based on Petr's comments in RHBZ#1794518.

The whole idea is: stick with non-aborting, but *also* don't fail the
whole function in case you had aborted with ABORT_ON_ERROR. Because
right now, even though we don't abort, we still fail the whole function.

> With setfiles -C, will all errors now be
> counted and cause setfiles to exit with 1, or will some errors still
> be fatal (exit with 255)?

The latter, definitely.

> Why on earth is setfiles originally calling exit(-1) at all?!  I
> didn't even know that was allowed.  I wrote a test program and this
> does indeed cause the exit status to be 255 (because the status is
> &-ed with 0xff).  Never seen a program before calling exit(-1).

I noticed that immediately, but that's not something I want to get
into... ;)

Laszlo


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH for-3.5 3/5] setfiles: remove useless "iamrestorecon" checks in option parsing
  2022-04-28  6:53 ` [PATCH for-3.5 3/5] setfiles: remove useless "iamrestorecon" checks in option parsing Laszlo Ersek
@ 2022-04-28 16:07   ` Daniel Burgener
  0 siblings, 0 replies; 11+ messages in thread
From: Daniel Burgener @ 2022-04-28 16:07 UTC (permalink / raw)
  To: Laszlo Ersek, SELinux List; +Cc: Richard W.M. Jones, Petr Lautrbach

On 4/28/2022 2:53 AM, Laszlo Ersek wrote:
> Commit 219eea83cea9 ("policycoreutils: setfiles/restorecon: fix -r/-R
> option", 2015-04-16) split the option strings between "setfiles" and
> "restorecon". Since that commit, an "iamrestorecon" check has only been
> necessary for an option that is (a) accepted by both "setfiles" and
> "restorecon", but (b) behaves differently between "setfiles" and
> "restorecon". Currently, the only such options are "-r" and "-R". Remove
> the "iamrestorecon" checks from the "setfiles"-only "-c" and "-d" options,
> and from the "restorecon"-only "-x" option.
> 
> Cc: "Richard W.M. Jones" <rjones@redhat.com>
> Cc: Petr Lautrbach <plautrba@redhat.com>
> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1794518
> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
> ---
>   policycoreutils/setfiles/setfiles.c | 11 +----------
>   1 file changed, 1 insertion(+), 10 deletions(-)
> 
> diff --git a/policycoreutils/setfiles/setfiles.c b/policycoreutils/setfiles/setfiles.c
> index cf504618d38f..aeec1fdcc2ab 100644
> --- a/policycoreutils/setfiles/setfiles.c
> +++ b/policycoreutils/setfiles/setfiles.c
> @@ -227,9 +227,6 @@ int main(int argc, char **argv)
>   			{
>   				FILE *policystream;
>   
> -				if (iamrestorecon)
> -					usage(argv[0]);
> -
>   				policyfile = optarg;
>   
>   				policystream = fopen(policyfile, "r");
> @@ -267,8 +264,6 @@ int main(int argc, char **argv)
>   			input_filename = optarg;
>   			break;
>   		case 'd':
> -			if (iamrestorecon)
> -				usage(argv[0]);
>   			r_opts.debug = 1;
>   			r_opts.log_matches =
>   					   SELINUX_RESTORECON_LOG_MATCHES;
> @@ -367,11 +362,7 @@ int main(int argc, char **argv)
>   			null_terminated = 1;
>   			break;
>   		case 'x':
> -			if (iamrestorecon) {
> -				r_opts.xdev = SELINUX_RESTORECON_XDEV;
> -			} else {
> -				usage(argv[0]);
> -			}
> +			r_opts.xdev = SELINUX_RESTORECON_XDEV;
>   			break;
>   		case 'T':
>   			nthreads = strtoull(optarg, &endptr, 10);

Reviewed-By: Daniel Burgener <dburgener@linux.microsoft.com>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH for-3.5 4/5] selinux_restorecon: introduce SELINUX_RESTORECON_COUNT_ERRORS
  2022-04-28  6:53 ` [PATCH for-3.5 4/5] selinux_restorecon: introduce SELINUX_RESTORECON_COUNT_ERRORS Laszlo Ersek
@ 2022-04-29  8:13   ` Petr Lautrbach
  2022-04-29 10:20     ` Laszlo Ersek
  0 siblings, 1 reply; 11+ messages in thread
From: Petr Lautrbach @ 2022-04-29  8:13 UTC (permalink / raw)
  To: SELinux List, Laszlo Ersek; +Cc: Richard W.M. Jones

Laszlo Ersek <lersek@redhat.com> writes:

> Currently, if the SELINUX_RESTORECON_ABORT_ON_ERROR flag is clear, then
> selinux_restorecon[_parallel]() does not abort the file tree walk upon an
> error, but the function itself fails the same, with the same (-1) return
> value. This in turn is reported by the setfiles(8) utility to its parent
> process with the same exit code (255).
>
> In libguestfs we want to proceed after setfiles(8) fails *at most* with
> such errors that occur during the file tree walk. We need setfiles(8) to
> exit with a distinct exit status in that situation.
>
> For this, introduce the SELINUX_RESTORECON_COUNT_ERRORS flag, and the
> corresponding selinux_restorecon_get_skipped_errors() function, for
> selinux_restorecon[_parallel]() to count, but otherwise ignore, errors
> during the file tree walk. When no other kind of error occurs, the
> relabeling functions will return zero, and the caller can fetch the number
> of errors ignored during the file tree walk with
> selinux_restorecon_get_skipped_errors().
>
> Importantly, when at least one such error is skipped, we don't write
> partial match digests for subdirectories, as any masked error means that
> any subdirectory may not have been completely relabeled.
>
> Cc: "Richard W.M. Jones" <rjones@redhat.com>
> Cc: Petr Lautrbach <plautrba@redhat.com>
> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1794518
> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
> ---
[...]
> --- a/libselinux/src/libselinux.map
> +++ b/libselinux/src/libselinux.map
> @@ -245,3 +245,8 @@ LIBSELINUX_3.4 {
>    global:
>      selinux_restorecon_parallel;
>  } LIBSELINUX_1.0;
> +
> +LIBSELINUX_3.5 {

It's still possible to put this into LIBSELINUX_3.4. Next week we will
release 3.4-rc3 and GA of 3.4 is planned two weeks later.


> +  global:
> +    selinux_restorecon_get_skipped_errors;
> +} LIBSELINUX_3.4;
> -- 
> 2.19.1.3.g30247aa5d201


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH for-3.5 4/5] selinux_restorecon: introduce SELINUX_RESTORECON_COUNT_ERRORS
  2022-04-29  8:13   ` Petr Lautrbach
@ 2022-04-29 10:20     ` Laszlo Ersek
  0 siblings, 0 replies; 11+ messages in thread
From: Laszlo Ersek @ 2022-04-29 10:20 UTC (permalink / raw)
  To: Petr Lautrbach, SELinux List; +Cc: Richard W.M. Jones

On 04/29/22 10:13, Petr Lautrbach wrote:
> Laszlo Ersek <lersek@redhat.com> writes:
> 
>> Currently, if the SELINUX_RESTORECON_ABORT_ON_ERROR flag is clear, then
>> selinux_restorecon[_parallel]() does not abort the file tree walk upon an
>> error, but the function itself fails the same, with the same (-1) return
>> value. This in turn is reported by the setfiles(8) utility to its parent
>> process with the same exit code (255).
>>
>> In libguestfs we want to proceed after setfiles(8) fails *at most* with
>> such errors that occur during the file tree walk. We need setfiles(8) to
>> exit with a distinct exit status in that situation.
>>
>> For this, introduce the SELINUX_RESTORECON_COUNT_ERRORS flag, and the
>> corresponding selinux_restorecon_get_skipped_errors() function, for
>> selinux_restorecon[_parallel]() to count, but otherwise ignore, errors
>> during the file tree walk. When no other kind of error occurs, the
>> relabeling functions will return zero, and the caller can fetch the number
>> of errors ignored during the file tree walk with
>> selinux_restorecon_get_skipped_errors().
>>
>> Importantly, when at least one such error is skipped, we don't write
>> partial match digests for subdirectories, as any masked error means that
>> any subdirectory may not have been completely relabeled.
>>
>> Cc: "Richard W.M. Jones" <rjones@redhat.com>
>> Cc: Petr Lautrbach <plautrba@redhat.com>
>> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1794518
>> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
>> ---
> [...]
>> --- a/libselinux/src/libselinux.map
>> +++ b/libselinux/src/libselinux.map
>> @@ -245,3 +245,8 @@ LIBSELINUX_3.4 {
>>    global:
>>      selinux_restorecon_parallel;
>>  } LIBSELINUX_1.0;
>> +
>> +LIBSELINUX_3.5 {
> 
> It's still possible to put this into LIBSELINUX_3.4. Next week we will
> release 3.4-rc3 and GA of 3.4 is planned two weeks later.

I assumed the project wouldn't assume new features after rc2 :)

I'll post v2, with this updated; but first I'll wait for the reviews to
complete.

Thanks!
Laszlo

> 
> 
>> +  global:
>> +    selinux_restorecon_get_skipped_errors;
>> +} LIBSELINUX_3.4;
>> -- 
>> 2.19.1.3.g30247aa5d201
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-04-29 10:20 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-28  6:53 [PATCH for-3.5 0/5] selinux_restorecon(3), setfiles(8): skip relabeling errors Laszlo Ersek
2022-04-28  6:53 ` [PATCH for-3.5 1/5] setfiles: fix up inconsistent indentation Laszlo Ersek
2022-04-28  6:53 ` [PATCH for-3.5 2/5] setfiles: remove useless assignment and comment (after RHBZ#1926386) Laszlo Ersek
2022-04-28  6:53 ` [PATCH for-3.5 3/5] setfiles: remove useless "iamrestorecon" checks in option parsing Laszlo Ersek
2022-04-28 16:07   ` Daniel Burgener
2022-04-28  6:53 ` [PATCH for-3.5 4/5] selinux_restorecon: introduce SELINUX_RESTORECON_COUNT_ERRORS Laszlo Ersek
2022-04-29  8:13   ` Petr Lautrbach
2022-04-29 10:20     ` Laszlo Ersek
2022-04-28  6:53 ` [PATCH for-3.5 5/5] setfiles: introduce the -C option for distinguishing file tree walk errors Laszlo Ersek
2022-04-28  9:22 ` [PATCH for-3.5 0/5] selinux_restorecon(3), setfiles(8): skip relabeling errors Richard W.M. Jones
2022-04-28  9:40   ` Laszlo Ersek

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.