Inter-revision diff: patch 6

Comparing v7 (message) to v6 (message)

--- v7
+++ v6
@@ -9,11 +9,6 @@
 Cc: Kees Cook <keescook@chromium.org>
 Cc: Shuah Khan <shuah@kernel.org>
 ---
-
-Changes since v6:
-* Add full combination tests for all file types, including block
-  devices, character devices, fifos, sockets and symlinks.
-* Properly save and restore initial sysctl value for all tests.
 
 Changes since v5:
 * Refactor with FIXTURE_VARIANT, which make the tests much more easy to
@@ -51,8 +46,8 @@
  tools/testing/selftests/openat2/Makefile      |   3 +-
  tools/testing/selftests/openat2/config        |   1 +
  tools/testing/selftests/openat2/helpers.h     |   1 +
- .../testing/selftests/openat2/omayexec_test.c | 325 ++++++++++++++++++
- 5 files changed, 332 insertions(+), 1 deletion(-)
+ .../testing/selftests/openat2/omayexec_test.c | 262 ++++++++++++++++++
+ 5 files changed, 269 insertions(+), 1 deletion(-)
  create mode 100644 tools/testing/selftests/openat2/config
  create mode 100644 tools/testing/selftests/openat2/omayexec_test.c
 
@@ -106,10 +101,10 @@
  #include "../kselftest.h"
 diff --git a/tools/testing/selftests/openat2/omayexec_test.c b/tools/testing/selftests/openat2/omayexec_test.c
 new file mode 100644
-index 000000000000..34b91f9d78d0
+index 000000000000..a33f31e59045
 --- /dev/null
 +++ b/tools/testing/selftests/openat2/omayexec_test.c
-@@ -0,0 +1,325 @@
+@@ -0,0 +1,262 @@
 +// SPDX-License-Identifier: GPL-2.0
 +/*
 + * Test O_MAYEXEC
@@ -126,7 +121,6 @@
 +#include <sys/capability.h>
 +#include <sys/mount.h>
 +#include <sys/stat.h>
-+#include <sys/sysmacros.h>
 +#include <unistd.h>
 +
 +#include "helpers.h"
@@ -139,13 +133,8 @@
 +static const char sysctl_path[] = "/proc/sys/fs/open_mayexec_enforce";
 +
 +static const char workdir_path[] = "./test-mount";
-+static const char reg_file_path[] = "./test-mount/regular_file";
++static const char file_path[] = "./test-mount/file";
 +static const char dir_path[] = "./test-mount/directory";
-+static const char symlink_path[] = "./test-mount/symlink";
-+static const char block_dev_path[] = "./test-mount/block_device";
-+static const char char_dev_path[] = "./test-mount/character_device";
-+static const char fifo_path[] = "./test-mount/fifo";
-+static const char sock_path[] = "./test-mount/socket";
 +
 +static void ignore_dac(struct __test_metadata *_metadata, int override)
 +{
@@ -179,91 +168,55 @@
 +}
 +
 +static void test_omx(struct __test_metadata *_metadata,
-+		const char *const path, const int no_mayexec_err_code,
-+		const int mayexec_err_code)
++		const char *const path, const int err_code)
 +{
 +	struct open_how how = {
-+		.flags = O_RDONLY | O_NOFOLLOW | O_CLOEXEC,
++		.flags = O_RDONLY | O_CLOEXEC,
 +	};
 +	int fd;
-+
-+	/* Do not block on pipes. */
-+	if (path == fifo_path)
-+		how.flags |= O_NONBLOCK;
 +
 +	/* Opens without O_MAYEXEC. */
 +	fd = sys_openat2(AT_FDCWD, path, &how);
-+	if (!no_mayexec_err_code) {
-+		ASSERT_LE(0, fd) {
-+			TH_LOG("Failed to openat2 %s: %d", path, -fd);
-+		}
++	ASSERT_LE(0, fd);
++	EXPECT_EQ(0, close(fd));
++
++	how.flags |= O_MAYEXEC;
++
++	/* Checks that O_MAYEXEC is ignored with open(2). */
++	fd = open(path, how.flags);
++	ASSERT_LE(0, fd);
++	EXPECT_EQ(0, close(fd));
++
++	/* Checks that O_MAYEXEC is ignored with openat(2). */
++	fd = openat(AT_FDCWD, path, how.flags);
++	ASSERT_LE(0, fd);
++	EXPECT_EQ(0, close(fd));
++
++	/* Opens with O_MAYEXEC. */
++	fd = sys_openat2(AT_FDCWD, path, &how);
++	if (!err_code) {
++		ASSERT_LE(0, fd);
 +		EXPECT_EQ(0, close(fd));
 +	} else {
-+		ASSERT_EQ(no_mayexec_err_code, fd) {
-+			TH_LOG("Wrong error for openat2 %s: %d", path, -fd);
-+		}
++		ASSERT_EQ(err_code, fd);
 +	}
-+
-+	how.flags |= O_MAYEXEC;
-+
-+	/* Checks that O_MAYEXEC is ignored with open(2). */
-+	fd = open(path, how.flags);
-+	if (!no_mayexec_err_code) {
-+		ASSERT_LE(0, fd) {
-+			TH_LOG("Failed to open %s: %d", path, errno);
-+		}
-+		EXPECT_EQ(0, close(fd));
-+	} else {
-+		ASSERT_EQ(no_mayexec_err_code, -errno);
-+	}
-+
-+	/* Checks that O_MAYEXEC is ignored with openat(2). */
-+	fd = openat(AT_FDCWD, path, how.flags);
-+	if (!no_mayexec_err_code) {
-+		ASSERT_LE(0, fd) {
-+			TH_LOG("Failed to openat %s: %d", path, errno);
-+		}
-+		EXPECT_EQ(0, close(fd));
-+	} else {
-+		ASSERT_EQ(no_mayexec_err_code, -errno);
-+	}
-+
-+	/* Opens with O_MAYEXEC. */
-+	fd = sys_openat2(AT_FDCWD, path, &how);
-+	if (!mayexec_err_code) {
-+		ASSERT_LE(0, fd) {
-+			TH_LOG("Failed to openat2 %s: %d", path, -fd);
-+		}
-+		EXPECT_EQ(0, close(fd));
-+	} else {
-+		ASSERT_EQ(mayexec_err_code, fd) {
-+			TH_LOG("Wrong error for openat2 %s: %d", path, -fd);
-+		}
-+	}
-+}
-+
-+static void test_file_types(struct __test_metadata *_metadata, const int err_code,
-+		const bool has_policy)
-+{
-+	test_omx(_metadata, reg_file_path, 0, err_code);
-+	test_omx(_metadata, dir_path, 0, -EISDIR);
-+	test_omx(_metadata, symlink_path, -ELOOP, -ELOOP);
-+	test_omx(_metadata, block_dev_path, 0, has_policy ? -EACCES : 0);
-+	test_omx(_metadata, char_dev_path, 0, has_policy ? -EACCES : 0);
-+	test_omx(_metadata, fifo_path, 0, has_policy ? -EACCES : 0);
-+	test_omx(_metadata, sock_path, -ENXIO, has_policy ? -EACCES : -ENXIO);
-+}
-+
-+static void test_files(struct __test_metadata *_metadata, const int err_code,
-+		const bool has_policy)
++}
++
++static void test_omx_dir_file(struct __test_metadata *_metadata, const int err_code)
++{
++	test_omx(_metadata, dir_path, -EISDIR);
++	test_omx(_metadata, file_path, err_code);
++}
++
++static void test_dir_file(struct __test_metadata *_metadata, const int err_code)
 +{
 +	/* Tests as root. */
 +	ignore_dac(_metadata, 1);
-+	test_file_types(_metadata, err_code, has_policy);
++	test_omx_dir_file(_metadata, err_code);
 +
 +	/* Tests without bypass. */
 +	ignore_dac(_metadata, 0);
-+	test_file_types(_metadata, err_code, has_policy);
++	test_omx_dir_file(_metadata, err_code);
 +}
 +
 +static void sysctl_write_char(struct __test_metadata *_metadata, const char value)
@@ -327,6 +280,8 @@
 +
 +FIXTURE_SETUP(omayexec)
 +{
++	int fd;
++
 +	/*
 +	 * Cleans previous workspace if any error previously happened (don't
 +	 * check errors).
@@ -340,20 +295,14 @@
 +				(variant->mount_exec ? 0 : MS_NOEXEC),
 +				"mode=0700,size=4k"));
 +
-+	/* Creates a regular file. */
-+	ASSERT_EQ(0, mknod(reg_file_path, S_IFREG | (variant->file_exec ? 0500 : 0400), 0));
-+	/* Creates a directory. */
-+	ASSERT_EQ(0, mkdir(dir_path, variant->file_exec ? 0500 : 0400));
-+	/* Creates a symlink pointing to the regular file. */
-+	ASSERT_EQ(0, symlink("regular_file", symlink_path));
-+	/* Creates a character device: /dev/null. */
-+	ASSERT_EQ(0, mknod(char_dev_path, S_IFCHR | 0400, makedev(1, 3)));
-+	/* Creates a block device: /dev/loop0 */
-+	ASSERT_EQ(0, mknod(block_dev_path, S_IFBLK | 0400, makedev(7, 0)));
-+	/* Creates a fifo. */
-+	ASSERT_EQ(0, mknod(fifo_path, S_IFIFO | 0400, 0));
-+	/* Creates a socket. */
-+	ASSERT_EQ(0, mknod(sock_path, S_IFSOCK | 0400, 0));
++	/* Creates a test file. */
++	fd = open(file_path, O_CREAT | O_RDONLY | O_CLOEXEC,
++			variant->file_exec ? 00500 : 00400);
++	ASSERT_LE(0, fd);
++	EXPECT_EQ(0, close(fd));
++
++	/* Creates a test directory. */
++	ASSERT_EQ(0, mkdir(dir_path, variant->file_exec ? 00500 : 00400));
 +
 +	/* Saves initial sysctl value. */
 +	self->initial_sysctl_value = sysctl_read_char(_metadata);
@@ -367,7 +316,7 @@
 +	/* Restores initial sysctl value. */
 +	sysctl_write_char(_metadata, self->initial_sysctl_value);
 +
-+	/* There is no need to unlink the test files. */
++	/* There is no need to unlink file_path nor dir_path. */
 +	ASSERT_EQ(0, umount(workdir_path));
 +	ASSERT_EQ(0, rmdir(workdir_path));
 +}
@@ -376,48 +325,31 @@
 +{
 +	/* Do not enforce anything. */
 +	sysctl_write_char(_metadata, '0');
-+	test_files(_metadata, 0, false);
++	test_dir_file(_metadata, 0);
 +}
 +
 +TEST_F(omayexec, sysctl_1)
 +{
 +	/* Enforces mount exec check. */
 +	sysctl_write_char(_metadata, '1');
-+	test_files(_metadata, variant->sysctl_err_code[0], true);
++	test_dir_file(_metadata, variant->sysctl_err_code[0]);
 +}
 +
 +TEST_F(omayexec, sysctl_2)
 +{
 +	/* Enforces file exec check. */
 +	sysctl_write_char(_metadata, '2');
-+	test_files(_metadata, variant->sysctl_err_code[1], true);
++	test_dir_file(_metadata, variant->sysctl_err_code[1]);
 +}
 +
 +TEST_F(omayexec, sysctl_3)
 +{
 +	/* Enforces mount and file exec check. */
 +	sysctl_write_char(_metadata, '3');
-+	test_files(_metadata, variant->sysctl_err_code[2], true);
-+}
-+
-+FIXTURE(cleanup) {
-+	char initial_sysctl_value;
-+};
-+
-+FIXTURE_SETUP(cleanup)
-+{
-+	/* Saves initial sysctl value. */
-+	self->initial_sysctl_value = sysctl_read_char(_metadata);
-+}
-+
-+FIXTURE_TEARDOWN(cleanup)
-+{
-+	/* Restores initial sysctl value. */
-+	ignore_sys_admin(_metadata, 1);
-+	sysctl_write_char(_metadata, self->initial_sysctl_value);
-+}
-+
-+TEST_F(cleanup, sysctl_access_write)
++	test_dir_file(_metadata, variant->sysctl_err_code[2]);
++}
++
++TEST(sysctl_access_write)
 +{
 +	int fd;
 +	ssize_t ret;
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help