[PATCH] --secontext: Implement displaying of expected context upon mismatch

Dmitry V. Levin ldv at altlinux.org
Fri Jan 7 15:24:00 UTC 2022


On Mon, Jan 03, 2022 at 08:24:37PM +0100, Renaud Métrich wrote:
> Right, it's because I'm expecting the contexts to work in the test to 
> make sure detection happens ...
> 
> Sorry for all this mess. I spawned a new Fedora with SELinux installed 
> but disabled to check all this, and another Fedora with SELinux not 
> installed at all.

Apparently, you attached an old version of the patch, but I've managed
to find the latest one. :)

It's now merged to master after a few tweaks here and there,
thanks for all the work required to make this happen!

Just for the reference, here is the diff:

diff --git a/NEWS b/NEWS
index 860e0dd50..75accb7cc 100644
--- a/NEWS
+++ b/NEWS
@@ -2,10 +2,10 @@ Noteworthy changes in release ?.?? (????-??-??)
 ===============================================
 
 * Improvements
-  * Implemented decoding of BPF_LINK_GET_NEXT_ID and BPF_LINK_GET_FD_BY_ID bpf
-    syscall commands.
   * Implemented --secontext=mismatch option to find mismatches in SELinux
     contexts.
+  * Implemented decoding of BPF_LINK_GET_NEXT_ID and BPF_LINK_GET_FD_BY_ID bpf
+    syscall commands.
   * Enhanced decoding of BPF_MAP_CREATE, BPF_PROG_TEST_RUN, and BPF_PROG_LOAD
     bpf syscall commands.
   * Enhanced decoding of BTRFS_IOC_FS_INFO ioctl command.
diff --git a/src/filter_qualify.c b/src/filter_qualify.c
index 5aa462a6c..e1e293c68 100644
--- a/src/filter_qualify.c
+++ b/src/filter_qualify.c
@@ -14,7 +14,9 @@
 #include "poke.h"
 #include "retval.h"
 #include "static_assert.h"
-#include "secontext.h"
+#ifdef ENABLE_SECONTEXT
+# include "secontext.h"
+#endif
 
 struct number_set *read_set;
 struct number_set *write_set;
@@ -621,6 +623,29 @@ qualify_kvm(const char *const str)
 	}
 }
 
+#ifdef ENABLE_SECONTEXT
+struct number_set *secontext_set;
+
+static int
+secontextstr_to_uint(const char *s)
+{
+	static const struct xlat_data secontext_strs[] = {
+		{ SECONTEXT_FULL,	"full" },
+		{ SECONTEXT_MISMATCH,	"mismatch" },
+	};
+
+	return (int) find_arg_val(s, secontext_strs, -1ULL, -1ULL);
+}
+
+void
+qualify_secontext(const char *const str)
+{
+	if (!secontext_set)
+		secontext_set = alloc_number_set_array(1);
+	qualify_tokens(str, secontext_set, secontextstr_to_uint, "secontext");
+}
+#endif
+
 static const struct qual_options {
 	const char *name;
 	void (*qualify)(const char *);
diff --git a/src/secontext.c b/src/secontext.c
index b27a45a20..a8e290e15 100644
--- a/src/secontext.c
+++ b/src/secontext.c
@@ -6,44 +6,21 @@
  */
 
 #include "defs.h"
-#include "filter.h"
-#include "number_set.h"
 
 #include <stdlib.h>
 #include <fcntl.h>
 #include <limits.h>
-#include <selinux/selinux.h>
-#include <selinux/label.h>
-#include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <selinux/selinux.h>
+#include <selinux/label.h>
 
+#include "largefile_wrappers.h"
+#include "number_set.h"
 #include "secontext.h"
 #include "xmalloc.h"
 #include "xstring.h"
 
-struct number_set *secontext_set;
-
-static int
-secontextstr_to_uint(const char *s)
-{
-	static const struct xlat_data secontext_strs[] = {
-		{ SECONTEXT_FULL,	"full" },
-		{ SECONTEXT_MISMATCH,	"mismatch" },
-	};
-
-	return (int) find_arg_val(s, secontext_strs, -1ULL, -1ULL);
-}
-
-void
-qualify_secontext(const char *const str)
-{
-	if (!secontext_set)
-		secontext_set = alloc_number_set_array(1);
-	qualify_tokens(str, secontext_set, secontextstr_to_uint,
-		       "secontext");
-}
-
 static int
 getcontext(int rc, char **secontext, char **result)
 {
@@ -87,15 +64,15 @@ getcontext(int rc, char **secontext, char **result)
 }
 
 static int
-get_expected_filecontext(const char *realpath, char **result)
+get_expected_filecontext(const char *path, char **result)
 {
-	static struct selabel_handle *hdl = NULL;
-	static bool disabled = false;
-
-	if (disabled)
-		return -1;
+	static struct selabel_handle *hdl;
 
 	if (!hdl) {
+		static bool disabled;
+		if (disabled)
+			return -1;
+
 		hdl = selabel_open(SELABEL_CTX_FILE, NULL, 0);
 		if (!hdl) {
 			perror_msg("could not open SELinux database, disabling "
@@ -105,16 +82,14 @@ get_expected_filecontext(const char *realpath, char **result)
 		}
 	}
 
-	struct stat statbuf;
-	if (stat(realpath, &statbuf) < 0) {
+	strace_stat_t stb;
+	if (stat_file(path, &stb) < 0) {
 		return -1;
 	}
 
 	char *secontext;
-	int rc = getcontext(selabel_lookup(hdl, &secontext, realpath,
-					   statbuf.st_mode),
-			    &secontext, result);
-	return rc;
+	return getcontext(selabel_lookup(hdl, &secontext, path, stb.st_mode),
+			  &secontext, result);
 }
 
 /*
@@ -156,12 +131,12 @@ selinux_getfdcon(pid_t pid, int fd, char **result)
 
 	char *secontext;
 	int rc = getcontext(getfilecon(linkpath, &secontext), &secontext, result);
-	if (rc == -1 || !is_number_in_set(SECONTEXT_MISMATCH, secontext_set))
+	if (rc < 0 || !is_number_in_set(SECONTEXT_MISMATCH, secontext_set))
 		return rc;
 
 	/*
 	 * We need to resolve the path, because selabel_lookup() doesn't
-	 * resolve anything. Using readlink() is sufficient here.
+	 * resolve anything.  Using readlink() is sufficient here.
 	 */
 
 	char buf[PATH_MAX];
@@ -171,7 +146,7 @@ selinux_getfdcon(pid_t pid, int fd, char **result)
 	buf[n] = '\0';
 
 	char *expected;
-	if (get_expected_filecontext(buf, &expected) == -1)
+	if (get_expected_filecontext(buf, &expected) < 0)
 		return 0;
 	if (strcmp(expected, *result) == 0) {
 		free(expected);
@@ -217,12 +192,12 @@ selinux_getfilecon(struct tcb *tcp, const char *path, char **result)
 
 	char *secontext;
 	rc = getcontext(getfilecon(fname, &secontext), &secontext, result);
-	if (rc == -1 || !is_number_in_set(SECONTEXT_MISMATCH, secontext_set))
+	if (rc < 0 || !is_number_in_set(SECONTEXT_MISMATCH, secontext_set))
 		return rc;
 
 	/*
 	 * We need to fully resolve the path, because selabel_lookup() doesn't
-	 * resolve anything. Using realpath() is the only solution here to make
+	 * resolve anything.  Using realpath() is the only solution here to make
 	 * sure the path is canonicalized.
 	 */
 
@@ -233,7 +208,7 @@ selinux_getfilecon(struct tcb *tcp, const char *path, char **result)
 	char *expected;
 	rc = get_expected_filecontext(resolved, &expected);
 	free(resolved);
-	if (rc == -1)
+	if (rc < 0)
 		return 0;
 	if (strcmp(expected, *result) == 0) {
 		free(expected);
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index ca906273b..8e6d9f3d7 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -12,8 +12,8 @@ accept4	-a37
 access	-a30 --trace-path=access_sample
 access--secontext	-a30 --secontext --trace-path=access_sample -e trace=access
 access--secontext_full	-a30 --secontext=full --trace-path=access_sample -e trace=access
-access--secontext_mismatch	-a30 --secontext=mismatch --trace-path=access_sample -e trace=access
 access--secontext_full_mismatch	-a30 --secontext=full,mismatch --trace-path=access_sample -e trace=access
+access--secontext_mismatch	-a30 --secontext=mismatch --trace-path=access_sample -e trace=access
 acct	-a20
 add_key	-a30 -s12
 adjtimex	-a15
@@ -34,8 +34,8 @@ chdir	-a10
 chmod	-a28
 chmod--secontext	-a28 -e secontext=!full,mismatch -e trace=chmod
 chmod--secontext_full	-a28 -e secontext=full -e trace=chmod
-chmod--secontext_mismatch	-a28 --secontext=mismatch -e trace=chmod
 chmod--secontext_full_mismatch	-a28 --secontext=mismatch,full -e trace=chmod
+chmod--secontext_mismatch	-a28 --secontext=mismatch -e trace=chmod
 chown	-a28
 chown32	-a31
 chroot	-a13
@@ -94,24 +94,24 @@ epoll_wait	-a26
 erestartsys	-a34 -e signal=none -e trace=recvfrom
 execve--secontext	+execve.test --secontext
 execve--secontext_full	+execve.test --secontext=full
-execve--secontext_mismatch	+execve.test --secontext=mismatch
 execve--secontext_full_mismatch	+execve.test --secontext=full,mismatch
+execve--secontext_mismatch	+execve.test --secontext=mismatch
 execveat
 execveat--secontext	--secontext --trace=execveat
 execveat--secontext_full	--secontext=full --trace=execveat
-execveat--secontext_mismatch	--secontext=mismatch --trace=execveat
 execveat--secontext_full_mismatch	--secontext=full,mismatch --trace=execveat
+execveat--secontext_mismatch	--secontext=mismatch --trace=execveat
 execveat-v	-v -e trace=execveat
 faccessat--secontext	+faccessat.test -a24 --secontext
 faccessat--secontext_full	+faccessat.test -a24 --secontext=full
-faccessat--secontext_mismatch	+faccessat.test -a24 --secontext=mismatch
 faccessat--secontext_full_mismatch	+faccessat.test -a24 --secontext=full,mismatch
+faccessat--secontext_mismatch	+faccessat.test -a24 --secontext=mismatch
 faccessat-P	-a23 --trace=faccessat -P /dev/full
 faccessat-y	+faccessat.test -a24 -y
 faccessat-y--secontext	+faccessat.test -a24 -y --secontext
 faccessat-y--secontext_full	+faccessat.test -a24 -y --secontext=full
-faccessat-y--secontext_mismatch	+faccessat.test -a24 -y --secontext=mismatch
 faccessat-y--secontext_full_mismatch	+faccessat.test -a24 -y --secontext=full,mismatch
+faccessat-y--secontext_mismatch	+faccessat.test -a24 -y --secontext=mismatch
 faccessat-yy	+faccessat.test -a24 -yy
 faccessat2-P	-a27 --trace=faccessat2 -P /dev/full
 faccessat2-y	+faccessat2.test -a28 -y
@@ -122,8 +122,8 @@ fanotify_init
 fanotify_mark	-a32
 fanotify_mark--secontext	-a32 --secontext -e trace=fanotify_mark
 fanotify_mark--secontext_full	-a32 --secontext=full -e trace=fanotify_mark
-fanotify_mark--secontext_mismatch	-a32 --secontext=mismatch -e trace=fanotify_mark
 fanotify_mark--secontext_full_mismatch	-a32 --secontext=full,mismatch -e trace=fanotify_mark
+fanotify_mark--secontext_mismatch	-a32 --secontext=mismatch -e trace=fanotify_mark
 fanotify_mark-Xabbrev	-a32 -Xabbrev -e trace=fanotify_mark
 fanotify_mark-Xraw	-a32 -Xraw -e trace=fanotify_mark
 fanotify_mark-Xverbose	-a32 -Xverbose -e trace=fanotify_mark
@@ -131,25 +131,25 @@ fchdir	-a11
 fchmod	-a15
 fchmod--secontext	-a15 --secontext -e trace=fchmod
 fchmod--secontext_full	-a15 --secontext=full -e trace=fchmod
-fchmod--secontext_mismatch	-a15 --secontext=mismatch -e trace=fchmod
 fchmod--secontext_full_mismatch	-a15 --secontext=full,mismatch -e trace=fchmod
+fchmod--secontext_mismatch	-a15 --secontext=mismatch -e trace=fchmod
 fchmod-y	-y -e trace=fchmod
 fchmod-y--secontext	-a15 -y --secontext -e trace=fchmod
 fchmod-y--secontext_full	-a15 -y --secontext=full -e trace=fchmod
-fchmod-y--secontext_mismatch	-a15 -y --secontext=mismatch -e trace=fchmod
 fchmod-y--secontext_full_mismatch	-a15 -y --secontext=full,mismatch -e trace=fchmod
+fchmod-y--secontext_mismatch	-a15 -y --secontext=mismatch -e trace=fchmod
 fchmodat
 fchmodat--secontext	--secontext -e trace=fchmodat
 fchmodat--secontext_full	--secontext=full -e trace=fchmodat
-fchmodat--secontext_mismatch	--secontext=mismatch -e trace=fchmodat
 fchmodat--secontext_full_mismatch	--secontext=full,mismatch -e trace=fchmodat
+fchmodat--secontext_mismatch	--secontext=mismatch -e trace=fchmodat
 fchown	-a16
 fchown32	-a18
 fchownat
 fchownat--secontext	--secontext -e trace=fchownat
 fchownat--secontext_full	--secontext=full -e trace=fchownat
-fchownat--secontext_mismatch	-e secontext=mismatch -e trace=fchownat
 fchownat--secontext_full_mismatch	-e secontext=full,mismatch -e trace=fchownat
+fchownat--secontext_mismatch	-e secontext=mismatch -e trace=fchownat
 fcntl	-a8
 fcntl--pidns-translation	test_pidns -a8 -e trace=fcntl
 fcntl64	-a8
@@ -158,8 +158,8 @@ fdatasync	-a14
 file_handle	-e trace=name_to_handle_at,open_by_handle_at
 file_handle--secontext	--secontext -e trace=name_to_handle_at,open_by_handle_at
 file_handle--secontext_full	--secontext=full -e trace=name_to_handle_at,open_by_handle_at
-file_handle--secontext_mismatch	--secontext=mismatch -e trace=name_to_handle_at,open_by_handle_at
 file_handle--secontext_full_mismatch	--secontext=full,mismatch -e trace=name_to_handle_at,open_by_handle_at
+file_handle--secontext_mismatch	--secontext=mismatch -e trace=name_to_handle_at,open_by_handle_at
 filter_seccomp	. "${srcdir=.}/filter_seccomp.sh"; test_prog_set --seccomp-bpf -f
 filter_seccomp-flag	../$NAME
 finit_module	-a25
@@ -445,8 +445,8 @@ link
 linkat
 linkat--secontext	--secontext -e trace=linkat
 linkat--secontext_full	--secontext=full -e trace=linkat
-linkat--secontext_mismatch	--secontext=mismatch -e trace=linkat
 linkat--secontext_full_mismatch	--secontext=full,mismatch -e trace=linkat
+linkat--secontext_mismatch	--secontext=mismatch -e trace=linkat
 lookup_dcookie	-a27
 lstat	-a31 --no-abbrev --trace-path=stat.sample --trace-path=/dev/full
 lstat64	-a32 --no-abbrev --trace-path=stat.sample --trace-path=/dev/full
@@ -619,15 +619,15 @@ oldstat	-a32 -v -P stat.sample -P /dev/full
 open	-a30 -P $NAME.sample
 open--secontext		-a30 -P open.sample --secontext --trace=open
 open--secontext_full	-a30 -P open.sample --secontext=full --trace=open
-open--secontext_mismatch		-a30 -P open.sample --secontext=mismatch --trace=open
 open--secontext_full_mismatch	-a30 -P open.sample --secontext=full,mismatch --trace=open
+open--secontext_mismatch		-a30 -P open.sample --secontext=mismatch --trace=open
 open_tree -a30 -y
 open_tree-P -a30 --decode-fds -P /dev/full -e trace=open_tree
 openat	-a36 -P $NAME.sample
 openat--secontext	-a36 -P openat.sample -P $PWD/openat.sample --secontext -e trace=openat
 openat--secontext_full	-a36 -P openat.sample -P $PWD/openat.sample --secontext=full -e trace=openat
-openat--secontext_mismatch	-a36 -P openat.sample -P $PWD/openat.sample --secontext=mismatch -e trace=openat
 openat--secontext_full_mismatch	-a36 -P openat.sample -P $PWD/openat.sample --secontext=full,mismatch -e trace=openat
+openat--secontext_mismatch	-a36 -P openat.sample -P $PWD/openat.sample --secontext=mismatch -e trace=openat
 openat2	-a35
 openat2-Xabbrev	--trace=openat2 -a35 -Xabbrev
 openat2-Xraw	--trace=openat2 -a32 -Xraw
diff --git a/tests/secontext.c b/tests/secontext.c
index 5957a0085..848eea98d 100644
--- a/tests/secontext.c
+++ b/tests/secontext.c
@@ -13,11 +13,10 @@
 # include <errno.h>
 # include <stdlib.h>
 # include <string.h>
+# include <sys/stat.h>
 # include <unistd.h>
 # include <selinux/selinux.h>
 # include <selinux/label.h>
-# include <sys/types.h>
-# include <sys/stat.h>
 
 # include "xmalloc.h"
 
@@ -107,7 +106,7 @@ raw_expected_secontext_full_file(const char *filename)
 	if (stat(resolved, &statbuf) < 0)
 		perror_msg_and_fail("stat: %s", resolved);
 
-	if (selabel_lookup(hdl, &secontext, resolved, statbuf.st_mode) == -1)
+	if (selabel_lookup(hdl, &secontext, resolved, statbuf.st_mode) < 0)
 		perror_msg_and_skip("selabel_lookup: %s", resolved);
 	free(resolved);
 
@@ -194,7 +193,8 @@ secontext_full_file(const char *filename, bool mismatch)
 	if (context && mismatch) {
 		char *expected = raw_expected_secontext_full_file(filename);
 		if (expected && strcmp(context, expected)) {
-			char *context_mismatch = xasprintf("%s!!%s", context, expected);
+			char *context_mismatch =
+				xasprintf("%s!!%s", context, expected);
 			free(context);
 			context = context_mismatch;
 		}
@@ -218,7 +218,8 @@ secontext_short_file(const char *filename, bool mismatch)
 	if (context && mismatch) {
 		char *expected = raw_expected_secontext_short_file(filename);
 		if (expected && strcmp(context, expected)) {
-			char *context_mismatch = xasprintf("%s!!%s", context, expected);
+			char *context_mismatch =
+				xasprintf("%s!!%s", context, expected);
 			free(context);
 			context = context_mismatch;
 		}

-- 
ldv


More information about the Strace-devel mailing list