All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Mickaël Salaün" <mic@digikod.net>
To: Jeff Xu <jeffxu@google.com>
Cc: "Mickaël Salaün" <mic@digikod.net>,
	gnoack@google.com, groeck@chromium.org, jorgelo@chromium.org,
	keescook@chromium.org, linux-security-module@vger.kernel.org
Subject: [PATCH] selftests/landlock: Improve ptrace_test with Yama
Date: Fri, 13 Jan 2023 18:53:08 +0100	[thread overview]
Message-ID: <20230113175308.50900-1-mic@digikod.net> (raw)
In-Reply-To: <20230113050755.1277736-2-jeffxu@google.com>

I found some issues running this new ptrace_test. Indeed, Yama doesn't
restrict PTRACE_MODE_READ whereas Landlock does. I also changed some
comments and socpe conditions. In fact, the final SKIP() wasn't a good
idea because it masks such potential errors; let's only use a log
message instead. I also removed the first SKIP() because we want
everything to be tested, and the MODE_READ does still matter anyway.

Please review this patch and squash it in yours.

Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20230113175308.50900-1-mic@digikod.net
---
 .../testing/selftests/landlock/ptrace_test.c  | 106 ++++++++++--------
 1 file changed, 57 insertions(+), 49 deletions(-)

diff --git a/tools/testing/selftests/landlock/ptrace_test.c b/tools/testing/selftests/landlock/ptrace_test.c
index c9d9f3001d0f..3c3ba37bf8ec 100644
--- a/tools/testing/selftests/landlock/ptrace_test.c
+++ b/tools/testing/selftests/landlock/ptrace_test.c
@@ -19,7 +19,7 @@
 
 #include "common.h"
 
-/* copy from yama_lsm.c */
+/* Copied from security/yama/yama_lsm.c */
 #define YAMA_SCOPE_DISABLED 0
 #define YAMA_SCOPE_RELATIONAL 1
 #define YAMA_SCOPE_CAPABILITY 2
@@ -70,7 +70,7 @@ static int get_yama_ptrace_scope(void)
 {
 	int ret;
 	char buf[2] = {};
-	int fd = open("/proc/sys/kernel/yama/ptrace_scope", O_RDONLY);
+	const int fd = open("/proc/sys/kernel/yama/ptrace_scope", O_RDONLY);
 
 	if (fd < 0)
 		return 0;
@@ -260,46 +260,48 @@ TEST_F(hierarchy, trace)
 	int yama_ptrace_scope;
 	char buf_parent;
 	long ret;
-	bool can_trace_child, can_trace_parent;
+	bool can_read_child, can_trace_child, can_read_parent, 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);
+	if (yama_ptrace_scope > YAMA_SCOPE_DISABLED)
+		TH_LOG("Incomplete tests due to Yama restrictions (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_read_child is true if a parent process can read its child
+	 * process, which is only the case when the parent process is not
+	 * isolated from the child with a dedicated Landlock domain.
 	 */
-	can_trace_child = !variant->domain_parent &&
-			  yama_ptrace_scope < YAMA_SCOPE_CAPABILITY;
+	can_read_child = !variant->domain_parent;
 
 	/*
-	 * 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_child is true if a parent process can trace its child
+	 * process.  This depends on two conditions:
+	 * - The parent process is not isolated from the child with a dedicated
+	 *   Landlock domain.
+	 * - Yama allows tracing children (up to YAMA_SCOPE_RELATIONAL).
 	 */
-	can_trace_parent = !variant->domain_child &&
-			   yama_ptrace_scope < YAMA_SCOPE_RELATIONAL;
+	can_trace_child = can_read_child &&
+			  yama_ptrace_scope <= YAMA_SCOPE_RELATIONAL;
+
+	/*
+	 * can_read_parent is true if a child process can read its parent
+	 * process, which is only the case when the child process is not
+	 * isolated from the parent with a dedicated Landlock domain.
+	 */
+	can_read_parent = !variant->domain_child;
+
+	/*
+	 * can_trace_parent is true if a child process can trace its parent
+	 * process.  This depends on two conditions:
+	 * - The child process is not isolated from the parent with a dedicated
+	 *   Landlock domain.
+	 * - Yama is disabled (YAMA_SCOPE_DISABLED).
+	 */
+	can_trace_parent = can_read_parent &&
+			   yama_ptrace_scope <= YAMA_SCOPE_DISABLED;
 
 	/*
 	 * Removes all effective and permitted capabilities to not interfere
@@ -330,16 +332,21 @@ TEST_F(hierarchy, trace)
 		/* Waits for the parent to be in a domain, if any. */
 		ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1));
 
-		/* Tests PTRACE_ATTACH and PTRACE_MODE_READ on the parent. */
+		/* Tests PTRACE_MODE_READ on the parent. */
 		err_proc_read = test_ptrace_read(parent);
+		if (can_read_parent) {
+			EXPECT_EQ(0, err_proc_read);
+		} else {
+			EXPECT_EQ(EACCES, err_proc_read);
+		}
+
+		/* Tests PTRACE_ATTACH on the parent. */
 		ret = ptrace(PTRACE_ATTACH, parent, NULL, 0);
-		if (!can_trace_parent) {
+		if (can_trace_parent) {
+			EXPECT_EQ(0, ret);
+		} else {
 			EXPECT_EQ(-1, ret);
 			EXPECT_EQ(EPERM, errno);
-			EXPECT_EQ(EACCES, err_proc_read);
-		} else {
-			EXPECT_EQ(0, ret);
-			EXPECT_EQ(0, err_proc_read);
 		}
 		if (ret == 0) {
 			ASSERT_EQ(parent, waitpid(parent, &status, 0));
@@ -349,11 +356,11 @@ TEST_F(hierarchy, trace)
 
 		/* Tests child PTRACE_TRACEME. */
 		ret = ptrace(PTRACE_TRACEME);
-		if (!can_trace_child) {
+		if (can_trace_child) {
+			EXPECT_EQ(0, ret);
+		} else {
 			EXPECT_EQ(-1, ret);
 			EXPECT_EQ(EPERM, errno);
-		} else {
-			EXPECT_EQ(0, ret);
 		}
 
 		/*
@@ -396,17 +403,23 @@ TEST_F(hierarchy, trace)
 		EXPECT_EQ(ESRCH, errno);
 	}
 
-	/* Tests PTRACE_ATTACH and PTRACE_MODE_READ on the child. */
+	/* Tests PTRACE_MODE_READ on the child. */
 	err_proc_read = test_ptrace_read(child);
+	if (can_read_child) {
+		EXPECT_EQ(0, err_proc_read);
+	} else {
+		EXPECT_EQ(EACCES, err_proc_read);
+	}
+
+	/* Tests PTRACE_ATTACH on the child. */
 	ret = ptrace(PTRACE_ATTACH, child, NULL, 0);
 	if (!can_trace_child) {
 		EXPECT_EQ(-1, ret);
 		EXPECT_EQ(EPERM, errno);
-		EXPECT_EQ(EACCES, err_proc_read);
 	} else {
 		EXPECT_EQ(0, ret);
-		EXPECT_EQ(0, err_proc_read);
 	}
+
 	if (ret == 0) {
 		ASSERT_EQ(child, waitpid(child, &status, 0));
 		ASSERT_EQ(1, WIFSTOPPED(status));
@@ -419,11 +432,6 @@ 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


  reply	other threads:[~2023-01-13 18:00 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 ` [PATCH v5 1/1] selftests/landlock: skip ptrace_test according to YAMA jeffxu
2023-01-13 17:53   ` Mickaël Salaün [this message]
2023-01-13 18:12     ` [PATCH] selftests/landlock: Improve ptrace_test with Yama 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=20230113175308.50900-1-mic@digikod.net \
    --to=mic@digikod.net \
    --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 \
    /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.