* [PATCH v2 01/10] landlock: Fix landlock_add_rule(2) documentation
2022-05-06 16:08 [PATCH v2 00/10] Minor Landlock fixes and new tests Mickaël Salaün
@ 2022-05-06 16:08 ` Mickaël Salaün
2022-05-06 16:08 ` [PATCH v2 02/10] selftests/landlock: Make tests build with old libc Mickaël Salaün
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Mickaël Salaün @ 2022-05-06 16:08 UTC (permalink / raw)
To: James Morris, Serge E . Hallyn
Cc: Mickaël Salaün, Jann Horn, Kees Cook,
Konstantin Meskhidze, Nathan Chancellor, Nick Desaulniers,
Paul Moore, Shuah Khan, linux-api, linux-kernel,
linux-security-module
It is not mandatory to pass a file descriptor obtained with the O_PATH
flag. Also, replace rule's accesses with ruleset's accesses.
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20220506160820.524344-2-mic@digikod.net
---
include/uapi/linux/landlock.h | 5 +++--
security/landlock/syscalls.c | 7 +++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h
index 15c31abb0d76..21c8d58283c9 100644
--- a/include/uapi/linux/landlock.h
+++ b/include/uapi/linux/landlock.h
@@ -62,8 +62,9 @@ struct landlock_path_beneath_attr {
*/
__u64 allowed_access;
/**
- * @parent_fd: File descriptor, open with ``O_PATH``, which identifies
- * the parent directory of a file hierarchy, or just a file.
+ * @parent_fd: File descriptor, preferably opened with ``O_PATH``,
+ * which identifies the parent directory of a file hierarchy, or just a
+ * file.
*/
__s32 parent_fd;
/*
diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c
index 2fde978bf8ca..7edc1d50e2bf 100644
--- a/security/landlock/syscalls.c
+++ b/security/landlock/syscalls.c
@@ -292,14 +292,13 @@ static int get_path_from_fd(const s32 fd, struct path *const path)
*
* - EOPNOTSUPP: Landlock is supported by the kernel but disabled at boot time;
* - EINVAL: @flags is not 0, or inconsistent access in the rule (i.e.
- * &landlock_path_beneath_attr.allowed_access is not a subset of the rule's
- * accesses);
+ * &landlock_path_beneath_attr.allowed_access is not a subset of the
+ * ruleset handled accesses);
* - ENOMSG: Empty accesses (e.g. &landlock_path_beneath_attr.allowed_access);
* - EBADF: @ruleset_fd is not a file descriptor for the current thread, or a
* member of @rule_attr is not a file descriptor as expected;
* - EBADFD: @ruleset_fd is not a ruleset file descriptor, or a member of
- * @rule_attr is not the expected file descriptor type (e.g. file open
- * without O_PATH);
+ * @rule_attr is not the expected file descriptor type;
* - EPERM: @ruleset_fd has no write access to the underlying ruleset;
* - EFAULT: @rule_attr inconsistency.
*/
--
2.35.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 02/10] selftests/landlock: Make tests build with old libc
2022-05-06 16:08 [PATCH v2 00/10] Minor Landlock fixes and new tests Mickaël Salaün
2022-05-06 16:08 ` [PATCH v2 01/10] landlock: Fix landlock_add_rule(2) documentation Mickaël Salaün
@ 2022-05-06 16:08 ` Mickaël Salaün
2022-05-06 16:08 ` [PATCH v2 03/10] selftests/landlock: Extend tests for minimal valid attribute size Mickaël Salaün
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Mickaël Salaün @ 2022-05-06 16:08 UTC (permalink / raw)
To: James Morris, Serge E . Hallyn
Cc: Mickaël Salaün, Jann Horn, Kees Cook,
Konstantin Meskhidze, Nathan Chancellor, Nick Desaulniers,
Paul Moore, Shuah Khan, linux-api, linux-kernel,
linux-security-module
Replace SYS_<syscall> with __NR_<syscall>. Using the __NR_<syscall>
notation, provided by UAPI, is useful to build tests on systems without
the SYS_<syscall> definitions.
Replace SYS_pivot_root with __NR_pivot_root, and SYS_move_mount with
__NR_move_mount.
Define renameat2() and RENAME_EXCHANGE if they are unknown to old build
systems.
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20220506160820.524344-3-mic@digikod.net
---
Changes since v1:
* Format with clang-format and rebase.
---
tools/testing/selftests/landlock/fs_test.c | 23 +++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index 28b01cb30c78..cc7fa7b17578 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -22,6 +22,19 @@
#include "common.h"
+#ifndef renameat2
+int renameat2(int olddirfd, const char *oldpath, int newdirfd,
+ const char *newpath, unsigned int flags)
+{
+ return syscall(__NR_renameat2, olddirfd, oldpath, newdirfd, newpath,
+ flags);
+}
+#endif
+
+#ifndef RENAME_EXCHANGE
+#define RENAME_EXCHANGE (1 << 1)
+#endif
+
#define TMP_DIR "tmp"
#define BINARY_PATH "./true"
@@ -1279,7 +1292,7 @@ TEST_F_FORK(layout1, rule_inside_mount_ns)
int ruleset_fd;
set_cap(_metadata, CAP_SYS_ADMIN);
- ASSERT_EQ(0, syscall(SYS_pivot_root, dir_s3d2, dir_s3d3))
+ ASSERT_EQ(0, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3))
{
TH_LOG("Failed to pivot root: %s", strerror(errno));
};
@@ -1313,7 +1326,7 @@ TEST_F_FORK(layout1, mount_and_pivot)
set_cap(_metadata, CAP_SYS_ADMIN);
ASSERT_EQ(-1, mount(NULL, dir_s3d2, NULL, MS_RDONLY, NULL));
ASSERT_EQ(EPERM, errno);
- ASSERT_EQ(-1, syscall(SYS_pivot_root, dir_s3d2, dir_s3d3));
+ ASSERT_EQ(-1, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3));
ASSERT_EQ(EPERM, errno);
clear_cap(_metadata, CAP_SYS_ADMIN);
}
@@ -1332,13 +1345,13 @@ TEST_F_FORK(layout1, move_mount)
ASSERT_LE(0, ruleset_fd);
set_cap(_metadata, CAP_SYS_ADMIN);
- ASSERT_EQ(0, syscall(SYS_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD,
+ ASSERT_EQ(0, syscall(__NR_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD,
dir_s1d2, 0))
{
TH_LOG("Failed to move mount: %s", strerror(errno));
}
- ASSERT_EQ(0, syscall(SYS_move_mount, AT_FDCWD, dir_s1d2, AT_FDCWD,
+ ASSERT_EQ(0, syscall(__NR_move_mount, AT_FDCWD, dir_s1d2, AT_FDCWD,
dir_s3d2, 0));
clear_cap(_metadata, CAP_SYS_ADMIN);
@@ -1346,7 +1359,7 @@ TEST_F_FORK(layout1, move_mount)
ASSERT_EQ(0, close(ruleset_fd));
set_cap(_metadata, CAP_SYS_ADMIN);
- ASSERT_EQ(-1, syscall(SYS_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD,
+ ASSERT_EQ(-1, syscall(__NR_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD,
dir_s1d2, 0));
ASSERT_EQ(EPERM, errno);
clear_cap(_metadata, CAP_SYS_ADMIN);
--
2.35.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 03/10] selftests/landlock: Extend tests for minimal valid attribute size
2022-05-06 16:08 [PATCH v2 00/10] Minor Landlock fixes and new tests Mickaël Salaün
2022-05-06 16:08 ` [PATCH v2 01/10] landlock: Fix landlock_add_rule(2) documentation Mickaël Salaün
2022-05-06 16:08 ` [PATCH v2 02/10] selftests/landlock: Make tests build with old libc Mickaël Salaün
@ 2022-05-06 16:08 ` Mickaël Salaün
2022-05-06 16:08 ` [PATCH v2 04/10] selftests/landlock: Add tests for unknown access rights Mickaël Salaün
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Mickaël Salaün @ 2022-05-06 16:08 UTC (permalink / raw)
To: James Morris, Serge E . Hallyn
Cc: Mickaël Salaün, Jann Horn, Kees Cook,
Konstantin Meskhidze, Nathan Chancellor, Nick Desaulniers,
Paul Moore, Shuah Khan, linux-api, linux-kernel,
linux-security-module
This might be useful when the struct landlock_ruleset_attr will get more
fields.
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20220506160820.524344-4-mic@digikod.net
---
Changes since v1:
* Format with clang-format and rebase.
---
tools/testing/selftests/landlock/base_test.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/selftests/landlock/base_test.c
index 3faeae4233a4..be9b937256ac 100644
--- a/tools/testing/selftests/landlock/base_test.c
+++ b/tools/testing/selftests/landlock/base_test.c
@@ -35,6 +35,8 @@ TEST(inconsistent_attr)
ASSERT_EQ(EINVAL, errno);
ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, 1, 0));
ASSERT_EQ(EINVAL, errno);
+ ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, 7, 0));
+ ASSERT_EQ(EINVAL, errno);
ASSERT_EQ(-1, landlock_create_ruleset(NULL, 1, 0));
/* The size if less than sizeof(struct landlock_attr_enforce). */
@@ -47,6 +49,9 @@ TEST(inconsistent_attr)
ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, page_size + 1, 0));
ASSERT_EQ(E2BIG, errno);
+ /* Checks minimal valid attribute size. */
+ ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, 8, 0));
+ ASSERT_EQ(ENOMSG, errno);
ASSERT_EQ(-1, landlock_create_ruleset(
ruleset_attr,
sizeof(struct landlock_ruleset_attr), 0));
--
2.35.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 04/10] selftests/landlock: Add tests for unknown access rights
2022-05-06 16:08 [PATCH v2 00/10] Minor Landlock fixes and new tests Mickaël Salaün
` (2 preceding siblings ...)
2022-05-06 16:08 ` [PATCH v2 03/10] selftests/landlock: Extend tests for minimal valid attribute size Mickaël Salaün
@ 2022-05-06 16:08 ` Mickaël Salaün
2022-05-06 16:08 ` [PATCH v2 05/10] selftests/landlock: Extend access right tests to directories Mickaël Salaün
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Mickaël Salaün @ 2022-05-06 16:08 UTC (permalink / raw)
To: James Morris, Serge E . Hallyn
Cc: Mickaël Salaün, Jann Horn, Kees Cook,
Konstantin Meskhidze, Nathan Chancellor, Nick Desaulniers,
Paul Moore, Shuah Khan, linux-api, linux-kernel,
linux-security-module
Make sure that trying to use unknown access rights returns an error.
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20220506160820.524344-5-mic@digikod.net
---
Changes since v1:
* Format with clang-format and rebase.
---
tools/testing/selftests/landlock/fs_test.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index cc7fa7b17578..f293b7e2a1a7 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -448,6 +448,22 @@ TEST_F_FORK(layout1, file_access_rights)
ASSERT_EQ(0, close(path_beneath.parent_fd));
}
+TEST_F_FORK(layout1, unknown_access_rights)
+{
+ __u64 access_mask;
+
+ for (access_mask = 1ULL << 63; access_mask != ACCESS_LAST;
+ access_mask >>= 1) {
+ struct landlock_ruleset_attr ruleset_attr = {
+ .handled_access_fs = access_mask,
+ };
+
+ ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr,
+ sizeof(ruleset_attr), 0));
+ ASSERT_EQ(EINVAL, errno);
+ }
+}
+
static void add_path_beneath(struct __test_metadata *const _metadata,
const int ruleset_fd, const __u64 allowed_access,
const char *const path)
--
2.35.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 05/10] selftests/landlock: Extend access right tests to directories
2022-05-06 16:08 [PATCH v2 00/10] Minor Landlock fixes and new tests Mickaël Salaün
` (3 preceding siblings ...)
2022-05-06 16:08 ` [PATCH v2 04/10] selftests/landlock: Add tests for unknown access rights Mickaël Salaün
@ 2022-05-06 16:08 ` Mickaël Salaün
2022-05-06 16:08 ` [PATCH v2 06/10] selftests/landlock: Fully test file rename with "remove" access Mickaël Salaün
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Mickaël Salaün @ 2022-05-06 16:08 UTC (permalink / raw)
To: James Morris, Serge E . Hallyn
Cc: Mickaël Salaün, Jann Horn, Kees Cook,
Konstantin Meskhidze, Nathan Chancellor, Nick Desaulniers,
Paul Moore, Shuah Khan, linux-api, linux-kernel,
linux-security-module
Make sure that all filesystem access rights can be tied to directories.
Rename layout1.file_access_rights to layout1.file_and_dir_access_rights
to reflect this change.
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20220506160820.524344-6-mic@digikod.net
---
Changes since v1:
* Format with clang-format and rebase.
---
tools/testing/selftests/landlock/fs_test.c | 30 ++++++++++++++++------
1 file changed, 22 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index f293b7e2a1a7..75f9358512df 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -418,11 +418,12 @@ TEST_F_FORK(layout1, inval)
/* clang-format on */
-TEST_F_FORK(layout1, file_access_rights)
+TEST_F_FORK(layout1, file_and_dir_access_rights)
{
__u64 access;
int err;
- struct landlock_path_beneath_attr path_beneath = {};
+ struct landlock_path_beneath_attr path_beneath_file = {},
+ path_beneath_dir = {};
struct landlock_ruleset_attr ruleset_attr = {
.handled_access_fs = ACCESS_ALL,
};
@@ -432,20 +433,33 @@ TEST_F_FORK(layout1, file_access_rights)
ASSERT_LE(0, ruleset_fd);
/* Tests access rights for files. */
- path_beneath.parent_fd = open(file1_s1d2, O_PATH | O_CLOEXEC);
- ASSERT_LE(0, path_beneath.parent_fd);
+ path_beneath_file.parent_fd = open(file1_s1d2, O_PATH | O_CLOEXEC);
+ ASSERT_LE(0, path_beneath_file.parent_fd);
+
+ /* Tests access rights for directories. */
+ path_beneath_dir.parent_fd =
+ open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC);
+ ASSERT_LE(0, path_beneath_dir.parent_fd);
+
for (access = 1; access <= ACCESS_LAST; access <<= 1) {
- path_beneath.allowed_access = access;
+ path_beneath_dir.allowed_access = access;
+ ASSERT_EQ(0, landlock_add_rule(ruleset_fd,
+ LANDLOCK_RULE_PATH_BENEATH,
+ &path_beneath_dir, 0));
+
+ path_beneath_file.allowed_access = access;
err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
- &path_beneath, 0);
- if ((access | ACCESS_FILE) == ACCESS_FILE) {
+ &path_beneath_file, 0);
+ if (access & ACCESS_FILE) {
ASSERT_EQ(0, err);
} else {
ASSERT_EQ(-1, err);
ASSERT_EQ(EINVAL, errno);
}
}
- ASSERT_EQ(0, close(path_beneath.parent_fd));
+ ASSERT_EQ(0, close(path_beneath_file.parent_fd));
+ ASSERT_EQ(0, close(path_beneath_dir.parent_fd));
+ ASSERT_EQ(0, close(ruleset_fd));
}
TEST_F_FORK(layout1, unknown_access_rights)
--
2.35.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 06/10] selftests/landlock: Fully test file rename with "remove" access
2022-05-06 16:08 [PATCH v2 00/10] Minor Landlock fixes and new tests Mickaël Salaün
` (4 preceding siblings ...)
2022-05-06 16:08 ` [PATCH v2 05/10] selftests/landlock: Extend access right tests to directories Mickaël Salaün
@ 2022-05-06 16:08 ` Mickaël Salaün
2022-05-06 16:08 ` [PATCH v2 07/10] selftests/landlock: Add tests for O_PATH Mickaël Salaün
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Mickaël Salaün @ 2022-05-06 16:08 UTC (permalink / raw)
To: James Morris, Serge E . Hallyn
Cc: Mickaël Salaün, Jann Horn, Kees Cook,
Konstantin Meskhidze, Nathan Chancellor, Nick Desaulniers,
Paul Moore, Shuah Khan, linux-api, linux-kernel,
linux-security-module
These tests were missing to check the check_access_path() call with all
combinations of maybe_remove(old_dentry) and maybe_remove(new_dentry).
Extend layout1.link with a new complementary test and check that
REMOVE_FILE is not required to link a file.
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20220506160820.524344-7-mic@digikod.net
---
Changes since v1:
* Extend layout1.link with a second rule layer to check that REMOVE_FILE
is not required to link a file.
* Format with clang-format and rebase.
---
tools/testing/selftests/landlock/fs_test.c | 41 +++++++++++++++++++---
1 file changed, 37 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index 75f9358512df..9165f6adf7b9 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -1659,15 +1659,21 @@ TEST_F_FORK(layout1, execute)
TEST_F_FORK(layout1, link)
{
- const struct rule rules[] = {
+ const struct rule layer1[] = {
{
.path = dir_s1d2,
.access = LANDLOCK_ACCESS_FS_MAKE_REG,
},
{},
};
- const int ruleset_fd =
- create_ruleset(_metadata, rules[0].access, rules);
+ const struct rule layer2[] = {
+ {
+ .path = dir_s1d3,
+ .access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
+ },
+ {},
+ };
+ int ruleset_fd = create_ruleset(_metadata, layer1[0].access, layer1);
ASSERT_LE(0, ruleset_fd);
@@ -1680,14 +1686,30 @@ TEST_F_FORK(layout1, link)
ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
ASSERT_EQ(EACCES, errno);
+
/* Denies linking because of reparenting. */
ASSERT_EQ(-1, link(file1_s2d1, file1_s1d2));
ASSERT_EQ(EXDEV, errno);
ASSERT_EQ(-1, link(file2_s1d2, file1_s1d3));
ASSERT_EQ(EXDEV, errno);
+ ASSERT_EQ(-1, link(file2_s1d3, file1_s1d2));
+ ASSERT_EQ(EXDEV, errno);
ASSERT_EQ(0, link(file2_s1d2, file1_s1d2));
ASSERT_EQ(0, link(file2_s1d3, file1_s1d3));
+
+ /* Prepares for next unlinks. */
+ ASSERT_EQ(0, unlink(file2_s1d2));
+ ASSERT_EQ(0, unlink(file2_s1d3));
+
+ ruleset_fd = create_ruleset(_metadata, layer2[0].access, layer2);
+ ASSERT_LE(0, ruleset_fd);
+ enforce_ruleset(_metadata, ruleset_fd);
+ ASSERT_EQ(0, close(ruleset_fd));
+
+ /* Checks that linkind doesn't require the ability to delete a file. */
+ ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
+ ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
}
TEST_F_FORK(layout1, rename_file)
@@ -1708,7 +1730,6 @@ TEST_F_FORK(layout1, rename_file)
ASSERT_LE(0, ruleset_fd);
- ASSERT_EQ(0, unlink(file1_s1d1));
ASSERT_EQ(0, unlink(file1_s1d2));
enforce_ruleset(_metadata, ruleset_fd);
@@ -1744,9 +1765,15 @@ TEST_F_FORK(layout1, rename_file)
ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d2, AT_FDCWD, file1_s2d1,
RENAME_EXCHANGE));
ASSERT_EQ(EACCES, errno);
+ /* Checks that file1_s2d1 cannot be removed (instead of ENOTDIR). */
+ ASSERT_EQ(-1, rename(dir_s2d2, file1_s2d1));
+ ASSERT_EQ(EACCES, errno);
ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, dir_s2d2,
RENAME_EXCHANGE));
ASSERT_EQ(EACCES, errno);
+ /* Checks that file1_s1d1 cannot be removed (instead of EISDIR). */
+ ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2));
+ ASSERT_EQ(EACCES, errno);
/* Renames files with different parents. */
ASSERT_EQ(-1, rename(file1_s2d2, file1_s1d2));
@@ -1809,9 +1836,15 @@ TEST_F_FORK(layout1, rename_dir)
ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s1d1, AT_FDCWD, dir_s2d1,
RENAME_EXCHANGE));
ASSERT_EQ(EACCES, errno);
+ /* Checks that dir_s1d2 cannot be removed (instead of ENOTDIR). */
+ ASSERT_EQ(-1, rename(dir_s1d2, file1_s1d1));
+ ASSERT_EQ(EACCES, errno);
ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, dir_s1d2,
RENAME_EXCHANGE));
ASSERT_EQ(EACCES, errno);
+ /* Checks that dir_s1d2 cannot be removed (instead of EISDIR). */
+ ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2));
+ ASSERT_EQ(EACCES, errno);
/*
* Exchanges and renames directory to the same parent, which allows
--
2.35.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 07/10] selftests/landlock: Add tests for O_PATH
2022-05-06 16:08 [PATCH v2 00/10] Minor Landlock fixes and new tests Mickaël Salaün
` (5 preceding siblings ...)
2022-05-06 16:08 ` [PATCH v2 06/10] selftests/landlock: Fully test file rename with "remove" access Mickaël Salaün
@ 2022-05-06 16:08 ` Mickaël Salaün
2022-05-06 16:08 ` [PATCH v2 08/10] landlock: Change landlock_add_rule(2) argument check ordering Mickaël Salaün
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Mickaël Salaün @ 2022-05-06 16:08 UTC (permalink / raw)
To: James Morris, Serge E . Hallyn
Cc: Mickaël Salaün, Jann Horn, Kees Cook,
Konstantin Meskhidze, Nathan Chancellor, Nick Desaulniers,
Paul Moore, Shuah Khan, linux-api, linux-kernel,
linux-security-module
The O_PATH flag is currently not handled by Landlock. Let's make sure
this behavior will remain consistent with the same ruleset over time.
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20220506160820.524344-8-mic@digikod.net
---
Changes since v1:
* New patch.
---
tools/testing/selftests/landlock/fs_test.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index 9165f6adf7b9..a8f54c4462eb 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -654,17 +654,23 @@ TEST_F_FORK(layout1, effective_access)
enforce_ruleset(_metadata, ruleset_fd);
ASSERT_EQ(0, close(ruleset_fd));
- /* Tests on a directory. */
+ /* Tests on a directory (with or without O_PATH). */
ASSERT_EQ(EACCES, test_open("/", O_RDONLY));
+ ASSERT_EQ(0, test_open("/", O_RDONLY | O_PATH));
ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY));
+ ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY | O_PATH));
ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY));
+ ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY | O_PATH));
+
ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY));
ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY));
ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY));
ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
- /* Tests on a file. */
+ /* Tests on a file (with or without O_PATH). */
ASSERT_EQ(EACCES, test_open(dir_s2d2, O_RDONLY));
+ ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_PATH));
+
ASSERT_EQ(0, test_open(file1_s2d2, O_RDONLY));
/* Checks effective read and write actions. */
--
2.35.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 08/10] landlock: Change landlock_add_rule(2) argument check ordering
2022-05-06 16:08 [PATCH v2 00/10] Minor Landlock fixes and new tests Mickaël Salaün
` (6 preceding siblings ...)
2022-05-06 16:08 ` [PATCH v2 07/10] selftests/landlock: Add tests for O_PATH Mickaël Salaün
@ 2022-05-06 16:08 ` Mickaël Salaün
2022-05-06 16:08 ` [PATCH v2 09/10] landlock: Change landlock_restrict_self(2) " Mickaël Salaün
2022-05-06 16:08 ` [PATCH v2 10/10] selftests/landlock: Test landlock_create_ruleset(2) argument " Mickaël Salaün
9 siblings, 0 replies; 11+ messages in thread
From: Mickaël Salaün @ 2022-05-06 16:08 UTC (permalink / raw)
To: James Morris, Serge E . Hallyn
Cc: Mickaël Salaün, Jann Horn, Kees Cook,
Konstantin Meskhidze, Nathan Chancellor, Nick Desaulniers,
Paul Moore, Shuah Khan, linux-api, linux-kernel,
linux-security-module
This makes more sense to first check the ruleset FD and then the rule
attribute. It will be useful to factor out code for other rule types.
Add inval_add_rule_arguments tests, extension of empty_path_beneath_attr
tests, to also check error ordering for landlock_add_rule(2).
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20220506160820.524344-9-mic@digikod.net
---
Changes since v1:
* New patch.
---
security/landlock/syscalls.c | 22 +++++++------
tools/testing/selftests/landlock/base_test.c | 34 ++++++++++++++++++--
2 files changed, 45 insertions(+), 11 deletions(-)
diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c
index 7edc1d50e2bf..a7396220c9d4 100644
--- a/security/landlock/syscalls.c
+++ b/security/landlock/syscalls.c
@@ -318,20 +318,24 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd,
if (flags)
return -EINVAL;
- if (rule_type != LANDLOCK_RULE_PATH_BENEATH)
- return -EINVAL;
-
- /* Copies raw user space buffer, only one type for now. */
- res = copy_from_user(&path_beneath_attr, rule_attr,
- sizeof(path_beneath_attr));
- if (res)
- return -EFAULT;
-
/* Gets and checks the ruleset. */
ruleset = get_ruleset_from_fd(ruleset_fd, FMODE_CAN_WRITE);
if (IS_ERR(ruleset))
return PTR_ERR(ruleset);
+ if (rule_type != LANDLOCK_RULE_PATH_BENEATH) {
+ err = -EINVAL;
+ goto out_put_ruleset;
+ }
+
+ /* Copies raw user space buffer, only one type for now. */
+ res = copy_from_user(&path_beneath_attr, rule_attr,
+ sizeof(path_beneath_attr));
+ if (res) {
+ err = -EFAULT;
+ goto out_put_ruleset;
+ }
+
/*
* Informs about useless rule: empty allowed_access (i.e. deny rules)
* are ignored in path walks.
diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/selftests/landlock/base_test.c
index be9b937256ac..18b779471dcb 100644
--- a/tools/testing/selftests/landlock/base_test.c
+++ b/tools/testing/selftests/landlock/base_test.c
@@ -121,20 +121,50 @@ TEST(inval_create_ruleset_flags)
ASSERT_EQ(EINVAL, errno);
}
-TEST(empty_path_beneath_attr)
+/* Tests ordering of syscall argument checks. */
+TEST(add_rule_checks_ordering)
{
const struct landlock_ruleset_attr ruleset_attr = {
.handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE,
};
+ struct landlock_path_beneath_attr path_beneath_attr = {
+ .allowed_access = LANDLOCK_ACCESS_FS_EXECUTE,
+ .parent_fd = -1,
+ };
const int ruleset_fd =
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
ASSERT_LE(0, ruleset_fd);
- /* Similar to struct landlock_path_beneath_attr.parent_fd = 0 */
+ /* Checks invalid flags. */
+ ASSERT_EQ(-1, landlock_add_rule(-1, 0, NULL, 1));
+ ASSERT_EQ(EINVAL, errno);
+
+ /* Checks invalid ruleset FD. */
+ ASSERT_EQ(-1, landlock_add_rule(-1, 0, NULL, 0));
+ ASSERT_EQ(EBADF, errno);
+
+ /* Checks invalid rule type. */
+ ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, 0, NULL, 0));
+ ASSERT_EQ(EINVAL, errno);
+
+ /* Checks invalid rule attr. */
ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
NULL, 0));
ASSERT_EQ(EFAULT, errno);
+
+ /* Checks invalid path_beneath.parent_fd. */
+ ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
+ &path_beneath_attr, 0));
+ ASSERT_EQ(EBADF, errno);
+
+ /* Checks valid call. */
+ path_beneath_attr.parent_fd =
+ open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC);
+ ASSERT_LE(0, path_beneath_attr.parent_fd);
+ ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
+ &path_beneath_attr, 0));
+ ASSERT_EQ(0, close(path_beneath_attr.parent_fd));
ASSERT_EQ(0, close(ruleset_fd));
}
--
2.35.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 09/10] landlock: Change landlock_restrict_self(2) check ordering
2022-05-06 16:08 [PATCH v2 00/10] Minor Landlock fixes and new tests Mickaël Salaün
` (7 preceding siblings ...)
2022-05-06 16:08 ` [PATCH v2 08/10] landlock: Change landlock_add_rule(2) argument check ordering Mickaël Salaün
@ 2022-05-06 16:08 ` Mickaël Salaün
2022-05-06 16:08 ` [PATCH v2 10/10] selftests/landlock: Test landlock_create_ruleset(2) argument " Mickaël Salaün
9 siblings, 0 replies; 11+ messages in thread
From: Mickaël Salaün @ 2022-05-06 16:08 UTC (permalink / raw)
To: James Morris, Serge E . Hallyn
Cc: Mickaël Salaün, Jann Horn, Kees Cook,
Konstantin Meskhidze, Nathan Chancellor, Nick Desaulniers,
Paul Moore, Shuah Khan, linux-api, linux-kernel,
linux-security-module
According to the Landlock goal to be a security feature available to
unprivileges processes, it makes more sense to first check for
no_new_privs before checking anything else (i.e. syscall arguments).
Merge inval_fd_enforce and unpriv_enforce_without_no_new_privs tests
into the new restrict_self_checks_ordering. This is similar to the
previous commit checking other syscalls.
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20220506160820.524344-10-mic@digikod.net
---
Changes since v1:
* New patch.
---
security/landlock/syscalls.c | 8 ++--
tools/testing/selftests/landlock/base_test.c | 47 +++++++++++++++-----
2 files changed, 41 insertions(+), 14 deletions(-)
diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c
index a7396220c9d4..507d43827afe 100644
--- a/security/landlock/syscalls.c
+++ b/security/landlock/syscalls.c
@@ -405,10 +405,6 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32,
if (!landlock_initialized)
return -EOPNOTSUPP;
- /* No flag for now. */
- if (flags)
- return -EINVAL;
-
/*
* Similar checks as for seccomp(2), except that an -EPERM may be
* returned.
@@ -417,6 +413,10 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32,
!ns_capable_noaudit(current_user_ns(), CAP_SYS_ADMIN))
return -EPERM;
+ /* No flag for now. */
+ if (flags)
+ return -EINVAL;
+
/* Gets and checks the ruleset. */
ruleset = get_ruleset_from_fd(ruleset_fd, FMODE_CAN_READ);
if (IS_ERR(ruleset))
diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/selftests/landlock/base_test.c
index 18b779471dcb..21fb33581419 100644
--- a/tools/testing/selftests/landlock/base_test.c
+++ b/tools/testing/selftests/landlock/base_test.c
@@ -168,22 +168,49 @@ TEST(add_rule_checks_ordering)
ASSERT_EQ(0, close(ruleset_fd));
}
-TEST(inval_fd_enforce)
+/* Tests ordering of syscall argument and permission checks. */
+TEST(restrict_self_checks_ordering)
{
+ const struct landlock_ruleset_attr ruleset_attr = {
+ .handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE,
+ };
+ struct landlock_path_beneath_attr path_beneath_attr = {
+ .allowed_access = LANDLOCK_ACCESS_FS_EXECUTE,
+ .parent_fd = -1,
+ };
+ const int ruleset_fd =
+ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
+
+ ASSERT_LE(0, ruleset_fd);
+ path_beneath_attr.parent_fd =
+ open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC);
+ ASSERT_LE(0, path_beneath_attr.parent_fd);
+ ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
+ &path_beneath_attr, 0));
+ ASSERT_EQ(0, close(path_beneath_attr.parent_fd));
+
+ /* Checks unprivileged enforcement without no_new_privs. */
+ drop_caps(_metadata);
+ ASSERT_EQ(-1, landlock_restrict_self(-1, -1));
+ ASSERT_EQ(EPERM, errno);
+ ASSERT_EQ(-1, landlock_restrict_self(-1, 0));
+ ASSERT_EQ(EPERM, errno);
+ ASSERT_EQ(-1, landlock_restrict_self(ruleset_fd, 0));
+ ASSERT_EQ(EPERM, errno);
+
ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
+ /* Checks invalid flags. */
+ ASSERT_EQ(-1, landlock_restrict_self(-1, -1));
+ ASSERT_EQ(EINVAL, errno);
+
+ /* Checks invalid ruleset FD. */
ASSERT_EQ(-1, landlock_restrict_self(-1, 0));
ASSERT_EQ(EBADF, errno);
-}
-
-TEST(unpriv_enforce_without_no_new_privs)
-{
- int err;
- drop_caps(_metadata);
- err = landlock_restrict_self(-1, 0);
- ASSERT_EQ(EPERM, errno);
- ASSERT_EQ(err, -1);
+ /* Checks valid call. */
+ ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0));
+ ASSERT_EQ(0, close(ruleset_fd));
}
TEST(ruleset_fd_io)
--
2.35.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 10/10] selftests/landlock: Test landlock_create_ruleset(2) argument check ordering
2022-05-06 16:08 [PATCH v2 00/10] Minor Landlock fixes and new tests Mickaël Salaün
` (8 preceding siblings ...)
2022-05-06 16:08 ` [PATCH v2 09/10] landlock: Change landlock_restrict_self(2) " Mickaël Salaün
@ 2022-05-06 16:08 ` Mickaël Salaün
9 siblings, 0 replies; 11+ messages in thread
From: Mickaël Salaün @ 2022-05-06 16:08 UTC (permalink / raw)
To: James Morris, Serge E . Hallyn
Cc: Mickaël Salaün, Jann Horn, Kees Cook,
Konstantin Meskhidze, Nathan Chancellor, Nick Desaulniers,
Paul Moore, Shuah Khan, linux-api, linux-kernel,
linux-security-module
Add inval_create_ruleset_arguments, extension of
inval_create_ruleset_flags, to also check error ordering for
landlock_create_ruleset(2).
This is similar to the previous commit checking landlock_add_rule(2).
Test coverage for security/landlock is 94.4% of 504 lines accorging to
gcc/gcov-11.
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20220506160820.524344-11-mic@digikod.net
---
Changes since v1:
* New patch.
---
tools/testing/selftests/landlock/base_test.c | 21 +++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/selftests/landlock/base_test.c
index 21fb33581419..35f64832b869 100644
--- a/tools/testing/selftests/landlock/base_test.c
+++ b/tools/testing/selftests/landlock/base_test.c
@@ -97,14 +97,17 @@ TEST(abi_version)
ASSERT_EQ(EINVAL, errno);
}
-TEST(inval_create_ruleset_flags)
+/* Tests ordering of syscall argument checks. */
+TEST(create_ruleset_checks_ordering)
{
const int last_flag = LANDLOCK_CREATE_RULESET_VERSION;
const int invalid_flag = last_flag << 1;
+ int ruleset_fd;
const struct landlock_ruleset_attr ruleset_attr = {
.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE,
};
+ /* Checks priority for invalid flags. */
ASSERT_EQ(-1, landlock_create_ruleset(NULL, 0, invalid_flag));
ASSERT_EQ(EINVAL, errno);
@@ -119,6 +122,22 @@ TEST(inval_create_ruleset_flags)
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr),
invalid_flag));
ASSERT_EQ(EINVAL, errno);
+
+ /* Checks too big ruleset_attr size. */
+ ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, -1, 0));
+ ASSERT_EQ(E2BIG, errno);
+
+ /* Checks too small ruleset_attr size. */
+ ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, 0));
+ ASSERT_EQ(EINVAL, errno);
+ ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 1, 0));
+ ASSERT_EQ(EINVAL, errno);
+
+ /* Checks valid call. */
+ ruleset_fd =
+ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
+ ASSERT_LE(0, ruleset_fd);
+ ASSERT_EQ(0, close(ruleset_fd));
}
/* Tests ordering of syscall argument checks. */
--
2.35.1
^ permalink raw reply [flat|nested] 11+ messages in thread