All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dorine Tipo <dorine.a.tipo@gmail.com>
To: "Mickaël Salaün" <mic@digikod.net>,
	skhan@linuxfoundation.org, "Paul Moore" <paul@paul-moore.com>,
	linux-security-module@vger.kernel.org, outreachy@lists.linux.dev
Cc: Dorine Tipo <dorine.a.tipo@gmail.com>,
	Linux-kernel-mentees-request@lists.linuxfoundation.org
Subject: [PATCH v4] Add test for io_uring openat access control with Landlock rules
Date: Thu,  4 Apr 2024 21:16:37 +0000	[thread overview]
Message-ID: <20240404211637.38472-1-dorine.a.tipo@gmail.com> (raw)

This v4 patch expands Landlock test coverage to include io_uring
operations. It also introduces a test for IORING_OP_OPENAT with Landlock
rules, verifying allowed and restricted O_RDONLY access. This makes sure that
IORING_OP_OPENAT is well covered from security vulnerabilities by
ensuring Landlock controls access through io_uring.

It also updates Makefile to include -luring in the LDLIBS variable.
This ensures the test code has access to the necessary library for
io_uring operations.

The previous implementation of tests for the io_uring operation
IORING_OP_OPENAT in the Landlock fs_test suite was found to be incorrect
and ineffective.
This patch removes the previous implementation and introduces a new set
of tests that cover both allowed and denied access scenarios.

Signed-off-by: Dorine Tipo <dorine.a.tipo@gmail.com>
Changes since V1:
V2: - Consolidated two dependent patches in the V1 series into one patch
      as suggested by Fabio.
    - Updated The subject line to be more descriptive.

V3: - Added "selftests/landlock" subject prefix
    - Revised wording in the commit message to accurately reflect the
      test functionality as suggested by Mickaël.
    - Updated the Fixture set_up and tear_down to create and remove the
      necesssary files and folders for testing access.
    - renamed allowed_ruleset_fd and disallowed_ruleset_fd to ruleset_fd
      as suggest by Mickaël.
    - Moved all variable declarations to the top of the function.
    - Refactored the code to test only one allowed and one restricted
      path instead of iterating through all the paths.
    - Added comments to explain what is happening in different blocks
      of code
    - Removed the clang-format markers.
    - Removed unused arguments in the function definition.
    - Added a final rule struct with a null path to the allowed_rule
      and disallowed_rule arrays as suggested by Fabio.
    - CC'd the missing mailing lists as suggested by Shuah.
    - All executables have been included in the .gitignore so no updates
      are necessary.

V4: - Removed the previous implementation of the tests as they were not
      correctly implemented.
---
 tools/testing/selftests/landlock/Makefile  |  4 +-
 tools/testing/selftests/landlock/fs_test.c | 85 ++++++++++++++++++++++
 2 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/landlock/Makefile b/tools/testing/selftests/landlock/Makefile
index 348e2dbdb4e0..ab47d1dadb62 100644
--- a/tools/testing/selftests/landlock/Makefile
+++ b/tools/testing/selftests/landlock/Makefile
@@ -13,11 +13,11 @@ TEST_GEN_PROGS := $(src_test:.c=)
 TEST_GEN_PROGS_EXTENDED := true

 # Short targets:
-$(TEST_GEN_PROGS): LDLIBS += -lcap
+$(TEST_GEN_PROGS): LDLIBS += -lcap -luring
 $(TEST_GEN_PROGS_EXTENDED): LDFLAGS += -static

 include ../lib.mk

 # Targets with $(OUTPUT)/ prefix:
-$(TEST_GEN_PROGS): LDLIBS += -lcap
+$(TEST_GEN_PROGS): LDLIBS += -lcap -luring
 $(TEST_GEN_PROGS_EXTENDED): LDFLAGS += -static
diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index 9a6036fbf289..d1fae72e99be 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -21,7 +21,10 @@
 #include <sys/stat.h>
 #include <sys/sysmacros.h>
 #include <sys/vfs.h>
+#include <sys/types.h>
 #include <unistd.h>
+#include <liburing.h>
+#include <linux/io_uring.h>

 #include "common.h"

@@ -4874,4 +4877,86 @@ TEST_F_FORK(layout3_fs, release_inodes)
 	ASSERT_EQ(EACCES, test_open(TMP_DIR, O_RDONLY));
 }

+/* test openat */
+static int test_openat(struct io_uring *ring, const char *path, int dfd)
+{
+	struct io_uring_cqe *cqe;
+	struct io_uring_sqe *sqe;
+	int ret;
+
+	sqe = io_uring_get_sqe(ring);
+	if (!sqe) {
+		fprintf(stderr, "get sqe failed\n");
+		goto err;
+	}
+	io_uring_prep_openat(sqe, dfd, path, O_RDONLY, 0);
+
+	ret = io_uring_submit(ring);
+	if (ret <= 0) {
+		fprintf(stderr, "sqe submit failed: %d\n", ret);
+		goto err;
+	}
+
+	ret = io_uring_wait_cqe(ring, &cqe);
+	if (ret < 0) {
+		fprintf(stderr, "wait completion %d\n", ret);
+		goto err;
+	}
+	ret = cqe->res;
+	io_uring_cqe_seen(ring, cqe);
+	return ret;
+err:
+	return -1;
+}
+
+TEST_F_FORK(layout1, openat_allowed)
+{
+	struct io_uring ring;
+	int ret;
+	const char *path = "file1_s1d3";
+	const struct rule rules[] = {
+		{
+			.path = path,
+			.access = LANDLOCK_ACCESS_FS_READ_FILE,
+		},
+		{
+			.path = NULL,
+		},
+	};
+	int ruleset_fd;
+
+	ruleset_fd = create_ruleset(_metadata, rules[0].access, rules);
+	ret = io_uring_queue_init(8, &ring, 0);
+
+	ASSERT_EQ(0, ret);
+	ASSERT_LE(0, ruleset_fd);
+	enforce_ruleset(_metadata, ruleset_fd);
+	ASSERT_EQ(0, test_openat(&ring, file1_s1d3, AT_FDCWD));
+}
+
+TEST_F_FORK(layout1, openat_denied)
+{
+	struct io_uring ring;
+	int ret;
+	const char *path = "file2_s1d3";
+	const struct rule rules[] = {
+		{
+			.path = path,
+			.access = LANDLOCK_ACCESS_FS_READ_FILE,
+		},
+		{
+			.path = NULL,
+		},
+	};
+	int ruleset_fd;
+
+	ruleset_fd = create_ruleset(_metadata, rules[0].access, rules);
+	ret = io_uring_queue_init(8, &ring, 0);
+
+	ASSERT_EQ(0, ret);
+	ASSERT_LE(0, ruleset_fd);
+	enforce_ruleset(_metadata, ruleset_fd);
+	ASSERT_EQ(EACCES, test_openat(&ring, file1_s1d3, AT_FDCWD));
+}
+
 TEST_HARNESS_MAIN
--
2.25.1


                 reply	other threads:[~2024-04-06 12:12 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20240404211637.38472-1-dorine.a.tipo@gmail.com \
    --to=dorine.a.tipo@gmail.com \
    --cc=Linux-kernel-mentees-request@lists.linuxfoundation.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mic@digikod.net \
    --cc=outreachy@lists.linux.dev \
    --cc=paul@paul-moore.com \
    --cc=skhan@linuxfoundation.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.