All of lore.kernel.org
 help / color / mirror / Atom feed
From: jeffxu@chromium.org
To: mic@digikod.net
Cc: jorgelo@chromium.org, keescook@chromium.org,
	linux-security-module@vger.kernel.org, groeck@chromium.org,
	gnoack@google.com, Jeff Xu <jeffxu@google.com>
Subject: [PATCH v5 1/1] selftests/landlock: skip ptrace_test according to YAMA
Date: Fri, 13 Jan 2023 05:07:55 +0000	[thread overview]
Message-ID: <20230113050755.1277736-2-jeffxu@google.com> (raw)
In-Reply-To: <20230113050755.1277736-1-jeffxu@google.com>

From: Jeff Xu <jeffxu@google.com>

Add check for yama setting for ptrace_test.

Signed-off-by: Jeff Xu <jeffxu@google.com>
---
 .../testing/selftests/landlock/ptrace_test.c  | 82 +++++++++++++++++--
 1 file changed, 76 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/landlock/ptrace_test.c b/tools/testing/selftests/landlock/ptrace_test.c
index c28ef98ff3ac..c9d9f3001d0f 100644
--- a/tools/testing/selftests/landlock/ptrace_test.c
+++ b/tools/testing/selftests/landlock/ptrace_test.c
@@ -19,6 +19,12 @@
 
 #include "common.h"
 
+/* copy from yama_lsm.c */
+#define YAMA_SCOPE_DISABLED 0
+#define YAMA_SCOPE_RELATIONAL 1
+#define YAMA_SCOPE_CAPABILITY 2
+#define YAMA_SCOPE_NO_ATTACH 3
+
 static void create_domain(struct __test_metadata *const _metadata)
 {
 	int ruleset_fd;
@@ -60,6 +66,25 @@ static int test_ptrace_read(const pid_t pid)
 	return 0;
 }
 
+static int get_yama_ptrace_scope(void)
+{
+	int ret;
+	char buf[2] = {};
+	int fd = open("/proc/sys/kernel/yama/ptrace_scope", O_RDONLY);
+
+	if (fd < 0)
+		return 0;
+
+	if (read(fd, buf, 1) < 0) {
+		close(fd);
+		return -1;
+	}
+
+	ret = atoi(buf);
+	close(fd);
+	return ret;
+}
+
 /* clang-format off */
 FIXTURE(hierarchy) {};
 /* clang-format on */
@@ -232,8 +257,49 @@ TEST_F(hierarchy, trace)
 	pid_t child, parent;
 	int status, err_proc_read;
 	int pipe_child[2], pipe_parent[2];
+	int yama_ptrace_scope;
 	char buf_parent;
 	long ret;
+	bool can_trace_child, can_trace_parent;
+
+	yama_ptrace_scope = get_yama_ptrace_scope();
+	ASSERT_LE(0, yama_ptrace_scope);
+
+	if (yama_ptrace_scope >= YAMA_SCOPE_NO_ATTACH)
+		SKIP(return, "Yama forbids any ptrace use (scope %d)",
+			   yama_ptrace_scope);
+
+	/*
+	 * can_trace_child: if a parent process can trace its child process.
+	 *
+	 * There are two conditions concerning landlock:
+	 * 1> the parent and child processes are in the same landlock domain or
+	 *	one beneath it (case: domain_both = true).
+	 * 2> yama allows tracing children (up to YAMA_SCOPE_RELATIONAL).
+	 * Both 1 and 2 need to be met for can_trace_child to be true.
+	 *
+	 * If a parent process has its own domain not shared with the child
+	 * process (case:domain_parent = true), then the parent can't trace the
+	 * child.
+	 */
+	can_trace_child = !variant->domain_parent &&
+			  yama_ptrace_scope < YAMA_SCOPE_CAPABILITY;
+
+	/*
+	 * can_trace_parent: if a child process can trace its parent process.
+	 *
+	 * There are two conditions concerning landlock:
+	 * 1> the parent and child process are in the same landlock domain or
+	 *	one beneath it.(case: domain_both = true).
+	 * 2> yama is disabled (YAMA_SCOPE_DISABLED).
+	 * Both 1 and 2 need to be met for can_trace_parent to be true.
+	 *
+	 * If a child process has its own domain not shared with the parent
+	 * process (case:domain_child = true, then the child can't trace the
+	 * parent.
+	 */
+	can_trace_parent = !variant->domain_child &&
+			   yama_ptrace_scope < YAMA_SCOPE_RELATIONAL;
 
 	/*
 	 * Removes all effective and permitted capabilities to not interfere
@@ -267,7 +333,7 @@ TEST_F(hierarchy, trace)
 		/* Tests PTRACE_ATTACH and PTRACE_MODE_READ on the parent. */
 		err_proc_read = test_ptrace_read(parent);
 		ret = ptrace(PTRACE_ATTACH, parent, NULL, 0);
-		if (variant->domain_child) {
+		if (!can_trace_parent) {
 			EXPECT_EQ(-1, ret);
 			EXPECT_EQ(EPERM, errno);
 			EXPECT_EQ(EACCES, err_proc_read);
@@ -283,7 +349,7 @@ TEST_F(hierarchy, trace)
 
 		/* Tests child PTRACE_TRACEME. */
 		ret = ptrace(PTRACE_TRACEME);
-		if (variant->domain_parent) {
+		if (!can_trace_child) {
 			EXPECT_EQ(-1, ret);
 			EXPECT_EQ(EPERM, errno);
 		} else {
@@ -296,9 +362,8 @@ TEST_F(hierarchy, trace)
 		 */
 		ASSERT_EQ(1, write(pipe_child[1], ".", 1));
 
-		if (!variant->domain_parent) {
+		if (can_trace_child)
 			ASSERT_EQ(0, raise(SIGSTOP));
-		}
 
 		/* Waits for the parent PTRACE_ATTACH test. */
 		ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1));
@@ -321,7 +386,7 @@ TEST_F(hierarchy, trace)
 	ASSERT_EQ(1, read(pipe_child[0], &buf_parent, 1));
 
 	/* Tests child PTRACE_TRACEME. */
-	if (!variant->domain_parent) {
+	if (can_trace_child) {
 		ASSERT_EQ(child, waitpid(child, &status, 0));
 		ASSERT_EQ(1, WIFSTOPPED(status));
 		ASSERT_EQ(0, ptrace(PTRACE_DETACH, child, NULL, 0));
@@ -334,7 +399,7 @@ TEST_F(hierarchy, trace)
 	/* Tests PTRACE_ATTACH and PTRACE_MODE_READ on the child. */
 	err_proc_read = test_ptrace_read(child);
 	ret = ptrace(PTRACE_ATTACH, child, NULL, 0);
-	if (variant->domain_parent) {
+	if (!can_trace_child) {
 		EXPECT_EQ(-1, ret);
 		EXPECT_EQ(EPERM, errno);
 		EXPECT_EQ(EACCES, err_proc_read);
@@ -354,6 +419,11 @@ TEST_F(hierarchy, trace)
 	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
 	    WEXITSTATUS(status) != EXIT_SUCCESS)
 		_metadata->passed = 0;
+
+	if (yama_ptrace_scope > 0)
+		SKIP(return,
+			   "Incomplete tests due to Yama restrictions (scope %d)",
+			   yama_ptrace_scope);
 }
 
 TEST_HARNESS_MAIN
-- 
2.39.0.314.g84b9a713c41-goog


  reply	other threads:[~2023-01-13  5:09 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-13  5:07 [PATCH v5 0/1] selftests/landlock: fix ptrace_test jeffxu
2023-01-13  5:07 ` jeffxu [this message]
2023-01-13 17:53   ` [PATCH] selftests/landlock: Improve ptrace_test with Yama Mickaël Salaün
2023-01-13 18:12     ` Mickaël Salaün
2023-01-14  2:02       ` Jeff Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230113050755.1277736-2-jeffxu@google.com \
    --to=jeffxu@chromium.org \
    --cc=gnoack@google.com \
    --cc=groeck@chromium.org \
    --cc=jeffxu@google.com \
    --cc=jorgelo@chromium.org \
    --cc=keescook@chromium.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mic@digikod.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.