Proposing SELinux support in strace

Dmitry V. Levin ldv at altlinux.org
Thu Mar 18 23:18:35 UTC 2021


On Thu, Mar 18, 2021 at 04:55:13PM +0100, Renaud Métrich wrote:
> Hello, I've just realized that the limitation on the mount namespace is 
> a real blocker in real world:
> 
> it appears that on systemd systems, all systemd services making use of 
> PrivateTmp get their own namespace (due to having their own /var/tmp), 
> which prevents the --secontext option from working for all files.

The very minimal fix that's readily available is for printing selinux
context associated with descriptors.  Since it can be obtained right from
procfs without falling back to path names, it should not be affected by
any differences in mountns or rootfs between strace and its tracee.

Could you try the following fix, please:

diff --git a/doc/strace.1.in b/doc/strace.1.in
index f63032b0f..e6ad7a9c0 100644
--- a/doc/strace.1.in
+++ b/doc/strace.1.in
@@ -1094,7 +1094,8 @@ strace's namespace, too.
 .if '@USE_SELINUX_FALSE@'#' is specified, print the complete context (user,
 .if '@USE_SELINUX_FALSE@'#' role, type and category) instead of just the type.
 .if '@USE_SELINUX_FALSE@'#' The current implementation has limitations, in
-.if '@USE_SELINUX_FALSE@'#' particular, SELinux contexts cannot be printed when
+.if '@USE_SELINUX_FALSE@'#' particular, SELinux contexts cannot be printed for
+.if '@USE_SELINUX_FALSE@'#' file names when
 .if '@USE_SELINUX_FALSE@'#' .B strace
 .if '@USE_SELINUX_FALSE@'#' and the tracee belong to different mount namespaces.
 .SS Statistics
diff --git a/src/selinux.c b/src/selinux.c
index 62e8e89e3..0f1edfe28 100644
--- a/src/selinux.c
+++ b/src/selinux.c
@@ -69,6 +69,29 @@ selinux_getpidcon(struct tcb *tcp, char **result)
 	return getcontext(getpidcon(proc_pid, &secontext), &secontext, result);
 }
 
+/*
+ * Retrieves the SELinux context of the given pid and descriptor.
+ * Memory must be freed.
+ * Returns 0 on success, -1 on failure.
+ */
+int
+selinux_getfdcon(pid_t pid, int fd, char **result)
+{
+	if (!selinux_context || pid <= 0 || fd < 0)
+		return -1;
+
+	int proc_pid = 0;
+	translate_pid(NULL, pid, PT_TID, &proc_pid);
+	if (!proc_pid)
+		return -1;
+
+	char linkpath[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3];
+	xsprintf(linkpath, "/proc/%u/fd/%u", proc_pid, fd);
+
+	char *secontext;
+	return getcontext(getfilecon(linkpath, &secontext), &secontext, result);
+}
+
 /*
  * Retrieves the SELinux context of the given path.
  * Memory must be freed.
diff --git a/src/selinux.h b/src/selinux.h
index ab39ea52e..68958f0cb 100644
--- a/src/selinux.h
+++ b/src/selinux.h
@@ -14,6 +14,7 @@
 extern bool selinux_context;
 extern bool selinux_context_full;
 
+int selinux_getfdcon(pid_t pid, int fd, char **context);
 int selinux_getpidcon(struct tcb *tcp, char **context);
 int selinux_getfilecon(struct tcb *tcp, const char *path, char **context);
 
diff --git a/src/util.c b/src/util.c
index 509b12f7f..b68129703 100644
--- a/src/util.c
+++ b/src/util.c
@@ -665,16 +665,16 @@ printfd_pid(struct tcb *tcp, pid_t pid, int fd)
 
 printed:
 		tprints(">");
-#ifdef USE_SELINUX
-		char *context;
-		if (!selinux_getfilecon(tcp, path, &context)) {
-			tprintf(" [%s]", context);
-			free(context);
-		}
-#endif
 	} else {
 		tprintf("%d", fd);
 	}
+#ifdef USE_SELINUX
+	char *context;
+	if (!selinux_getfdcon(pid, fd, &context)) {
+		tprintf(" [%s]", context);
+		free(context);
+	}
+#endif
 }
 
 void

-- 
ldv


More information about the Strace-devel mailing list