Inter-revision diff: patch 4

Comparing v4 (message) to v7 (message)

--- v4
+++ v7
@@ -1,428 +1,203 @@
-Test propagation of noexec mount points or file executability through
-files open with or without O_MAYEXEC.
-
+When the O_MAYEXEC flag is passed, openat2(2) may be subject to
+additional restrictions depending on a security policy managed by the
+kernel through a sysctl or implemented by an LSM thanks to the
+inode_permission hook.  This new flag is ignored by open(2) and
+openat(2) because of their unspecified flags handling.  When used with
+openat2(2), the default behavior is only to forbid to open a directory.
+
+The underlying idea is to be able to restrict scripts interpretation
+according to a policy defined by the system administrator.  For this to
+be possible, script interpreters must use the O_MAYEXEC flag
+appropriately.  To be fully effective, these interpreters also need to
+handle the other ways to execute code: command line parameters (e.g.,
+option -e for Perl), module loading (e.g., option -m for Python), stdin,
+file sourcing, environment variables, configuration files, etc.
+According to the threat model, it may be acceptable to allow some script
+interpreters (e.g. Bash) to interpret commands from stdin, may it be a
+TTY or a pipe, because it may not be enough to (directly) perform
+syscalls.  Further documentation can be found in a following patch.
+
+Even without enforced security policy, userland interpreters can set it
+to enforce the system policy at their level, knowing that it will not
+break anything on running systems which do not care about this feature.
+However, on systems which want this feature enforced, there will be
+knowledgeable people (i.e. sysadmins who enforced O_MAYEXEC
+deliberately) to manage it.  A simple security policy implementation,
+configured through a dedicated sysctl, is available in a following
+patch.
+
+O_MAYEXEC should not be confused with the O_EXEC flag which is intended
+for execute-only, which obviously doesn't work for scripts.  However, a
+similar behavior could be implemented in userland with O_PATH:
+https://lore.kernel.org/lkml/1e2f6913-42f2-3578-28ed-567f6a4bdda1@digikod.net/
+
+The implementation of O_MAYEXEC almost duplicates what execve(2) and
+uselib(2) are already doing: setting MAY_OPENEXEC in acc_mode (which can
+then be checked as MAY_EXEC, if enforced).
+
+This is an updated subset of the patch initially written by Vincent
+Strubel for CLIP OS 4:
+https://github.com/clipos-archive/src_platform_clip-patches/blob/f5cb330d6b684752e403b4e41b39f7004d88e561/1901_open_mayexec.patch
+This patch has been used for more than 12 years with customized script
+interpreters.  Some examples (with the original O_MAYEXEC) can be found
+here:
+https://github.com/clipos-archive/clipos4_portage-overlay/search?q=O_MAYEXEC
+
+Co-developed-by: Vincent Strubel <vincent.strubel@ssi.gouv.fr>
+Signed-off-by: Vincent Strubel <vincent.strubel@ssi.gouv.fr>
+Co-developed-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
+Signed-off-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
 Signed-off-by: Mickaël Salaün <mic@digikod.net>
-Reviewed-by: Thibaut Sautereau <thibaut.sautereau@ssi.gouv.fr>
 Cc: Aleksa Sarai <cyphar@cyphar.com>
 Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: Deven Bowers <deven.desai@linux.microsoft.com>
 Cc: Kees Cook <keescook@chromium.org>
-Cc: Shuah Khan <shuah@kernel.org>
 ---
 
+Changes since v6:
+* Do not set __FMODE_EXEC for now because of inconsistent behavior:
+  https://lore.kernel.org/lkml/202007160822.CCDB5478@keescook/
+* Returns EISDIR when opening a directory with O_MAYEXEC.
+* Removed Deven Bowers and Kees Cook Reviewed-by tags because of the
+  current update.
+
+Changes since v5:
+* Update commit message.
+
 Changes since v3:
-* Replace RESOLVE_MAYEXEC with O_MAYEXEC.
-* Add tests to check that O_MAYEXEC is ignored by open(2) and openat(2).
+* Switch back to O_MAYEXEC, but only handle it with openat2(2) which
+  checks unknown flags (suggested by Aleksa Sarai). Cf.
+  https://lore.kernel.org/lkml/20200430015429.wuob7m5ofdewubui@yavin.dot.cyphar.com/
 
 Changes since v2:
-* Move tests from exec/ to openat2/ .
-* Replace O_MAYEXEC with RESOLVE_MAYEXEC from openat2(2).
-* Cleanup tests.
+* Replace O_MAYEXEC with RESOLVE_MAYEXEC from openat2(2).  This change
+  enables to not break existing application using bogus O_* flags that
+  may be ignored by current kernels by using a new dedicated flag, only
+  usable through openat2(2) (suggested by Jeff Layton).  Using this flag
+  will results in an error if the running kernel does not support it.
+  User space needs to manage this case, as with other RESOLVE_* flags.
+  The best effort approach to security (for most common distros) will
+  simply consists of ignoring such an error and retry without
+  RESOLVE_MAYEXEC.  However, a fully controlled system may which to
+  error out if such an inconsistency is detected.
 
 Changes since v1:
-* Move tests from yama/ to exec/ .
-* Fix _GNU_SOURCE in kselftest_harness.h .
-* Add a new test sysctl_access_write to check if CAP_MAC_ADMIN is taken
-  into account.
-* Test directory execution which is always forbidden since commit
-  73601ea5b7b1 ("fs/open.c: allow opening only regular files during
-  execve()"), and also check that even the root user can not bypass file
-  execution checks.
-* Make sure delete_workspace() always as enough right to succeed.
-* Cosmetic cleanup.
+* Set __FMODE_EXEC when using O_MAYEXEC to make this information
+  available through the new fanotify/FAN_OPEN_EXEC event (suggested by
+  Jan Kara and Matthew Bobrowski):
+  https://lore.kernel.org/lkml/20181213094658.GA996@lithium.mbobrowski.org/
 ---
- tools/testing/selftests/kselftest_harness.h   |   3 +
- 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 | 330 ++++++++++++++++++
- 5 files changed, 337 insertions(+), 1 deletion(-)
- create mode 100644 tools/testing/selftests/openat2/config
- create mode 100644 tools/testing/selftests/openat2/omayexec_test.c
-
-diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
-index 2bb8c81fc0b4..f6e056ba4a13 100644
---- a/tools/testing/selftests/kselftest_harness.h
-+++ b/tools/testing/selftests/kselftest_harness.h
-@@ -50,7 +50,10 @@
- #ifndef __KSELFTEST_HARNESS_H
- #define __KSELFTEST_HARNESS_H
- 
-+#ifndef _GNU_SOURCE
- #define _GNU_SOURCE
-+#endif
+ fs/fcntl.c                       | 2 +-
+ fs/namei.c                       | 4 ++--
+ fs/open.c                        | 6 ++++++
+ include/linux/fcntl.h            | 2 +-
+ include/linux/fs.h               | 2 ++
+ include/uapi/asm-generic/fcntl.h | 7 +++++++
+ 6 files changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/fs/fcntl.c b/fs/fcntl.c
+index 2e4c0fa2074b..0357ad667563 100644
+--- a/fs/fcntl.c
++++ b/fs/fcntl.c
+@@ -1033,7 +1033,7 @@ static int __init fcntl_init(void)
+ 	 * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
+ 	 * is defined as O_NONBLOCK on some platforms and not on others.
+ 	 */
+-	BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ !=
++	BUILD_BUG_ON(22 - 1 /* for O_RDONLY being 0 */ !=
+ 		HWEIGHT32(
+ 			(VALID_OPEN_FLAGS & ~(O_NONBLOCK | O_NDELAY)) |
+ 			__FMODE_EXEC | __FMODE_NONOTIFY));
+diff --git a/fs/namei.c b/fs/namei.c
+index ddc9b25540fe..3f074ec77390 100644
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -428,7 +428,7 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask)
+ /**
+  * inode_permission - Check for access rights to a given inode
+  * @inode: Inode to check permission on
+- * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
++ * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC, %MAY_OPENEXEC)
+  *
+  * Check for read/write/execute permissions on an inode.  We use fs[ug]id for
+  * this, letting us set arbitrary permissions for filesystem access without
+@@ -2849,7 +2849,7 @@ static int may_open(const struct path *path, int acc_mode, int flag)
+ 	case S_IFLNK:
+ 		return -ELOOP;
+ 	case S_IFDIR:
+-		if (acc_mode & (MAY_WRITE | MAY_EXEC))
++		if (acc_mode & (MAY_WRITE | MAY_EXEC | MAY_OPENEXEC))
+ 			return -EISDIR;
+ 		break;
+ 	case S_IFBLK:
+diff --git a/fs/open.c b/fs/open.c
+index 623b7506a6db..21c2c1020574 100644
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -987,6 +987,8 @@ inline struct open_how build_open_how(int flags, umode_t mode)
+ 		.mode = mode & S_IALLUGO,
+ 	};
+ 
++	/* O_MAYEXEC is ignored by syscalls relying on build_open_how(). */
++	how.flags &= ~O_MAYEXEC;
+ 	/* O_PATH beats everything else. */
+ 	if (how.flags & O_PATH)
+ 		how.flags &= O_PATH_FLAGS;
+@@ -1054,6 +1056,10 @@ inline int build_open_flags(const struct open_how *how, struct open_flags *op)
+ 	if (flags & __O_SYNC)
+ 		flags |= O_DSYNC;
+ 
++	/* Checks execution permissions on open. */
++	if (flags & O_MAYEXEC)
++		acc_mode |= MAY_OPENEXEC;
 +
- #include <asm/types.h>
- #include <errno.h>
- #include <stdbool.h>
-diff --git a/tools/testing/selftests/openat2/Makefile b/tools/testing/selftests/openat2/Makefile
-index 4b93b1417b86..cb98bdb4d5b1 100644
---- a/tools/testing/selftests/openat2/Makefile
-+++ b/tools/testing/selftests/openat2/Makefile
-@@ -1,7 +1,8 @@
- # SPDX-License-Identifier: GPL-2.0-or-later
- 
- CFLAGS += -Wall -O2 -g -fsanitize=address -fsanitize=undefined
--TEST_GEN_PROGS := openat2_test resolve_test rename_attack_test
-+LDLIBS += -lcap
-+TEST_GEN_PROGS := openat2_test resolve_test rename_attack_test omayexec_test
- 
- include ../lib.mk
- 
-diff --git a/tools/testing/selftests/openat2/config b/tools/testing/selftests/openat2/config
-new file mode 100644
-index 000000000000..dd53c266bf52
---- /dev/null
-+++ b/tools/testing/selftests/openat2/config
-@@ -0,0 +1 @@
-+CONFIG_SYSCTL=y
-diff --git a/tools/testing/selftests/openat2/helpers.h b/tools/testing/selftests/openat2/helpers.h
-index a6ea27344db2..1dcd3e1e2f38 100644
---- a/tools/testing/selftests/openat2/helpers.h
-+++ b/tools/testing/selftests/openat2/helpers.h
-@@ -9,6 +9,7 @@
- 
- #define _GNU_SOURCE
- #include <stdint.h>
-+#include <stdbool.h>
- #include <errno.h>
- #include <linux/types.h>
- #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..7052c852daf8
---- /dev/null
-+++ b/tools/testing/selftests/openat2/omayexec_test.c
-@@ -0,0 +1,330 @@
-+// SPDX-License-Identifier: GPL-2.0
+ 	op->open_flag = flags;
+ 
+ 	/* O_TRUNC implies we need access checks for write permissions */
+diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
+index 7bcdcf4f6ab2..e188a360fa5f 100644
+--- a/include/linux/fcntl.h
++++ b/include/linux/fcntl.h
+@@ -10,7 +10,7 @@
+ 	(O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC | \
+ 	 O_APPEND | O_NDELAY | O_NONBLOCK | O_NDELAY | __O_SYNC | O_DSYNC | \
+ 	 FASYNC	| O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW | \
+-	 O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE)
++	 O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE | O_MAYEXEC)
+ 
+ /* List of all valid flags for the how->upgrade_mask argument: */
+ #define VALID_UPGRADE_FLAGS \
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index f5abba86107d..56f835c9a87a 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -101,6 +101,8 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
+ #define MAY_CHDIR		0x00000040
+ /* called from RCU mode, don't block */
+ #define MAY_NOT_BLOCK		0x00000080
++/* the inode is opened with O_MAYEXEC */
++#define MAY_OPENEXEC		0x00000100
+ 
+ /*
+  * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
+diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
+index 9dc0bf0c5a6e..bca90620119f 100644
+--- a/include/uapi/asm-generic/fcntl.h
++++ b/include/uapi/asm-generic/fcntl.h
+@@ -97,6 +97,13 @@
+ #define O_NDELAY	O_NONBLOCK
+ #endif
+ 
 +/*
-+ * Test O_MAYEXEC
-+ *
-+ * Copyright © 2018-2020 ANSSI
-+ *
-+ * Author: Mickaël Salaün <mic@digikod.net>
++ * Code execution from file is intended, checks such permission.  A simple
++ * policy can be enforced system-wide as explained in
++ * Documentation/admin-guide/sysctl/fs.rst .
 + */
++#define O_MAYEXEC	040000000
 +
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <sys/capability.h>
-+#include <sys/mount.h>
-+#include <sys/stat.h>
-+#include <unistd.h>
-+
-+#include "helpers.h"
-+#include "../kselftest_harness.h"
-+
-+#ifndef O_MAYEXEC
-+#define O_MAYEXEC		040000000
-+#endif
-+
-+#define SYSCTL_MAYEXEC	"/proc/sys/fs/open_mayexec_enforce"
-+
-+#define BIN_DIR		"./test-mount"
-+#define BIN_PATH	BIN_DIR "/file"
-+#define DIR_PATH	BIN_DIR "/directory"
-+
-+#define ALLOWED		1
-+#define DENIED		0
-+
-+static void ignore_dac(struct __test_metadata *_metadata, int override)
-+{
-+	cap_t caps;
-+	const cap_value_t cap_val[2] = {
-+		CAP_DAC_OVERRIDE,
-+		CAP_DAC_READ_SEARCH,
-+	};
-+
-+	caps = cap_get_proc();
-+	ASSERT_NE(NULL, caps);
-+	ASSERT_EQ(0, cap_set_flag(caps, CAP_EFFECTIVE, 2, cap_val,
-+				override ? CAP_SET : CAP_CLEAR));
-+	ASSERT_EQ(0, cap_set_proc(caps));
-+	EXPECT_EQ(0, cap_free(caps));
-+}
-+
-+static void ignore_mac(struct __test_metadata *_metadata, int override)
-+{
-+	cap_t caps;
-+	const cap_value_t cap_val[1] = {
-+		CAP_MAC_ADMIN,
-+	};
-+
-+	caps = cap_get_proc();
-+	ASSERT_NE(NULL, caps);
-+	ASSERT_EQ(0, cap_set_flag(caps, CAP_EFFECTIVE, 1, cap_val,
-+				override ? CAP_SET : CAP_CLEAR));
-+	ASSERT_EQ(0, cap_set_proc(caps));
-+	EXPECT_EQ(0, cap_free(caps));
-+}
-+
-+static void test_omx(struct __test_metadata *_metadata,
-+		const char *const path, const int exec_allowed)
-+{
-+	struct open_how how = {
-+		.flags = O_RDONLY | O_CLOEXEC,
-+	};
-+	int fd;
-+
-+	/* Opens without O_MAYEXEC. */
-+	fd = sys_openat2(AT_FDCWD, path, &how);
-+	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 (exec_allowed) {
-+		ASSERT_LE(0, fd);
-+		EXPECT_EQ(0, close(fd));
-+	} else {
-+		ASSERT_EQ(-EACCES, fd);
-+	}
-+}
-+
-+static void test_omx_dir_file(struct __test_metadata *_metadata,
-+		const char *const dir_path, const char *const file_path,
-+		const int exec_allowed)
-+{
-+	/*
-+	 * Directory execution is always denied since commit 73601ea5b7b1
-+	 * ("fs/open.c: allow opening only regular files during execve()").
-+	 */
-+	test_omx(_metadata, dir_path, DENIED);
-+	test_omx(_metadata, file_path, exec_allowed);
-+}
-+
-+static void test_dir_file(struct __test_metadata *_metadata,
-+		const char *const dir_path, const char *const file_path,
-+		const int exec_allowed)
-+{
-+	/* Tests as root. */
-+	ignore_dac(_metadata, 1);
-+	test_omx_dir_file(_metadata, dir_path, file_path, exec_allowed);
-+
-+	/* Tests without bypass. */
-+	ignore_dac(_metadata, 0);
-+	test_omx_dir_file(_metadata, dir_path, file_path, exec_allowed);
-+}
-+
-+static void sysctl_write(struct __test_metadata *_metadata,
-+		const char *path, const char *value)
-+{
-+	int fd;
-+	size_t len_value;
-+	ssize_t len_wrote;
-+
-+	fd = open(path, O_WRONLY | O_CLOEXEC);
-+	ASSERT_LE(0, fd);
-+	len_value = strlen(value);
-+	len_wrote = write(fd, value, len_value);
-+	ASSERT_EQ(len_wrote, len_value);
-+	EXPECT_EQ(0, close(fd));
-+}
-+
-+static void create_workspace(struct __test_metadata *_metadata,
-+		int mount_exec, int file_exec)
-+{
-+	int fd;
-+
-+	/*
-+	 * Cleans previous workspace if any error previously happened (don't
-+	 * check errors).
-+	 */
-+	umount(BIN_DIR);
-+	rmdir(BIN_DIR);
-+
-+	/* Creates a clean mount point. */
-+	ASSERT_EQ(0, mkdir(BIN_DIR, 00700));
-+	ASSERT_EQ(0, mount("test", BIN_DIR, "tmpfs",
-+				MS_MGC_VAL | (mount_exec ? 0 : MS_NOEXEC),
-+				"mode=0700,size=4k"));
-+
-+	/* Creates a test file. */
-+	fd = open(BIN_PATH, O_CREAT | O_RDONLY | O_CLOEXEC,
-+			file_exec ? 00500 : 00400);
-+	ASSERT_LE(0, fd);
-+	EXPECT_EQ(0, close(fd));
-+
-+	/* Creates a test directory. */
-+	ASSERT_EQ(0, mkdir(DIR_PATH, file_exec ? 00500 : 00400));
-+}
-+
-+static void delete_workspace(struct __test_metadata *_metadata)
-+{
-+	ignore_mac(_metadata, 1);
-+	sysctl_write(_metadata, SYSCTL_MAYEXEC, "0");
-+
-+	/* There is no need to unlink BIN_PATH nor DIR_PATH. */
-+	ASSERT_EQ(0, umount(BIN_DIR));
-+	ASSERT_EQ(0, rmdir(BIN_DIR));
-+}
-+
-+FIXTURE_DATA(mount_exec_file_exec) { };
-+
-+FIXTURE_SETUP(mount_exec_file_exec)
-+{
-+	create_workspace(_metadata, 1, 1);
-+}
-+
-+FIXTURE_TEARDOWN(mount_exec_file_exec)
-+{
-+	delete_workspace(_metadata);
-+}
-+
-+TEST_F(mount_exec_file_exec, mount)
-+{
-+	/* Enforces mount exec check. */
-+	sysctl_write(_metadata, SYSCTL_MAYEXEC, "1");
-+	test_dir_file(_metadata, DIR_PATH, BIN_PATH, ALLOWED);
-+}
-+
-+TEST_F(mount_exec_file_exec, file)
-+{
-+	/* Enforces file exec check. */
-+	sysctl_write(_metadata, SYSCTL_MAYEXEC, "2");
-+	test_dir_file(_metadata, DIR_PATH, BIN_PATH, ALLOWED);
-+}
-+
-+TEST_F(mount_exec_file_exec, mount_file)
-+{
-+	/* Enforces mount and file exec check. */
-+	sysctl_write(_metadata, SYSCTL_MAYEXEC, "3");
-+	test_dir_file(_metadata, DIR_PATH, BIN_PATH, ALLOWED);
-+}
-+
-+FIXTURE_DATA(mount_exec_file_noexec) { };
-+
-+FIXTURE_SETUP(mount_exec_file_noexec)
-+{
-+	create_workspace(_metadata, 1, 0);
-+}
-+
-+FIXTURE_TEARDOWN(mount_exec_file_noexec)
-+{
-+	delete_workspace(_metadata);
-+}
-+
-+TEST_F(mount_exec_file_noexec, mount)
-+{
-+	/* Enforces mount exec check. */
-+	sysctl_write(_metadata, SYSCTL_MAYEXEC, "1");
-+	test_dir_file(_metadata, DIR_PATH, BIN_PATH, ALLOWED);
-+}
-+
-+TEST_F(mount_exec_file_noexec, file)
-+{
-+	/* Enforces file exec check. */
-+	sysctl_write(_metadata, SYSCTL_MAYEXEC, "2");
-+	test_dir_file(_metadata, DIR_PATH, BIN_PATH, DENIED);
-+}
-+
-+TEST_F(mount_exec_file_noexec, mount_file)
-+{
-+	/* Enforces mount and file exec check. */
-+	sysctl_write(_metadata, SYSCTL_MAYEXEC, "3");
-+	test_dir_file(_metadata, DIR_PATH, BIN_PATH, DENIED);
-+}
-+
-+FIXTURE_DATA(mount_noexec_file_exec) { };
-+
-+FIXTURE_SETUP(mount_noexec_file_exec)
-+{
-+	create_workspace(_metadata, 0, 1);
-+}
-+
-+FIXTURE_TEARDOWN(mount_noexec_file_exec)
-+{
-+	delete_workspace(_metadata);
-+}
-+
-+TEST_F(mount_noexec_file_exec, mount)
-+{
-+	/* Enforces mount exec check. */
-+	sysctl_write(_metadata, SYSCTL_MAYEXEC, "1");
-+	test_dir_file(_metadata, DIR_PATH, BIN_PATH, DENIED);
-+}
-+
-+TEST_F(mount_noexec_file_exec, file)
-+{
-+	/* Enforces file exec check. */
-+	sysctl_write(_metadata, SYSCTL_MAYEXEC, "2");
-+	test_dir_file(_metadata, DIR_PATH, BIN_PATH, ALLOWED);
-+}
-+
-+TEST_F(mount_noexec_file_exec, mount_file)
-+{
-+	/* Enforces mount and file exec check. */
-+	sysctl_write(_metadata, SYSCTL_MAYEXEC, "3");
-+	test_dir_file(_metadata, DIR_PATH, BIN_PATH, DENIED);
-+}
-+
-+FIXTURE_DATA(mount_noexec_file_noexec) { };
-+
-+FIXTURE_SETUP(mount_noexec_file_noexec)
-+{
-+	create_workspace(_metadata, 0, 0);
-+}
-+
-+FIXTURE_TEARDOWN(mount_noexec_file_noexec)
-+{
-+	delete_workspace(_metadata);
-+}
-+
-+TEST_F(mount_noexec_file_noexec, mount)
-+{
-+	/* Enforces mount exec check. */
-+	sysctl_write(_metadata, SYSCTL_MAYEXEC, "1");
-+	test_dir_file(_metadata, DIR_PATH, BIN_PATH, DENIED);
-+}
-+
-+TEST_F(mount_noexec_file_noexec, file)
-+{
-+	/* Enforces file exec check. */
-+	sysctl_write(_metadata, SYSCTL_MAYEXEC, "2");
-+	test_dir_file(_metadata, DIR_PATH, BIN_PATH, DENIED);
-+}
-+
-+TEST_F(mount_noexec_file_noexec, mount_file)
-+{
-+	/* Enforces mount and file exec check. */
-+	sysctl_write(_metadata, SYSCTL_MAYEXEC, "3");
-+	test_dir_file(_metadata, DIR_PATH, BIN_PATH, DENIED);
-+}
-+
-+TEST(sysctl_access_write)
-+{
-+	int fd;
-+	ssize_t len_wrote;
-+
-+	ignore_mac(_metadata, 1);
-+	sysctl_write(_metadata, SYSCTL_MAYEXEC, "0");
-+
-+	ignore_mac(_metadata, 0);
-+	fd = open(SYSCTL_MAYEXEC, O_WRONLY | O_CLOEXEC);
-+	ASSERT_LE(0, fd);
-+	len_wrote = write(fd, "0", 1);
-+	ASSERT_EQ(len_wrote, -1);
-+	EXPECT_EQ(0, close(fd));
-+
-+	ignore_mac(_metadata, 1);
-+}
-+
-+TEST_HARNESS_MAIN
+ #define F_DUPFD		0	/* dup */
+ #define F_GETFD		1	/* get close_on_exec */
+ #define F_SETFD		2	/* set/clear close_on_exec */
 -- 
-2.26.2
-
+2.27.0
+
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help