Re: [LTP] [PATCH v2 05/11] Add landlock01 test
From: Li Wang <hidden>
Date: 2024-07-11 07:31:00
On Thu, Jul 11, 2024 at 3:07 PM Andrea Cervesato [off-list ref] wrote:
Hi, On 7/11/24 05:16, Li Wang wrote: Hi Andrea, On Thu, Jul 11, 2024 at 2:02 AM Andrea Cervesato [off-list ref] wrote:quoted
From: Andrea Cervesato <andrea.cervesato@suse.com> This test verifies that landlock_create_ruleset syscall fails with the right error codes: - EINVAL Unknown flags, or unknown access, or too small size - E2BIG size is too big - EFAULT attr was not a valid address - ENOMSG Empty accesses (i.e., attr->handled_access_fs is 0) Reviewed-by: Li Wang <redacted> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com> --- runtest/syscalls | 2 + testcases/kernel/syscalls/landlock/.gitignore | 1 + testcases/kernel/syscalls/landlock/Makefile | 7 ++ testcases/kernel/syscalls/landlock/landlock01.c | 92 ++++++++++++++++++++++ .../kernel/syscalls/landlock/landlock_common.h | 74 +++++++++++++++++ 5 files changed, 176 insertions(+)diff --git a/runtest/syscalls b/runtest/syscalls index b6cadb2df..667e419a3 100644 --- a/runtest/syscalls +++ b/runtest/syscalls@@ -684,6 +684,8 @@ kill11 kill11 kill12 kill12 kill13 kill13 +landlock01 landlock01 + lchown01 lchown01 lchown01_16 lchown01_16 lchown02 lchown02diff --git a/testcases/kernel/syscalls/landlock/.gitignoreb/testcases/kernel/syscalls/landlock/.gitignore new file mode 100644 index 000000000..b69f9b94a--- /dev/null +++ b/testcases/kernel/syscalls/landlock/.gitignore@@ -0,0 +1 @@ +landlock01diff --git a/testcases/kernel/syscalls/landlock/Makefileb/testcases/kernel/syscalls/landlock/Makefile new file mode 100644 index 000000000..8cf1b9024--- /dev/null +++ b/testcases/kernel/syscalls/landlock/Makefile@@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com> + +top_srcdir ?= ../../../.. + +include $(top_srcdir)/include/mk/testcases.mk +include $(top_srcdir)/include/mk/generic_leaf_target.mkdiff --git a/testcases/kernel/syscalls/landlock/landlock01.cb/testcases/kernel/syscalls/landlock/landlock01.c new file mode 100644 index 000000000..90f338fb0--- /dev/null +++ b/testcases/kernel/syscalls/landlock/landlock01.c@@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com> + */ + +/*\ + * [Description] + * + * This test verifies that landlock_create_ruleset syscall fails with the right + * error codes: + * + * - EINVAL Unknown flags, or unknown access, or too small size + * - E2BIG size is too big + * - EFAULT attr was not a valid address + * - ENOMSG Empty accesses (i.e., attr->handled_access_fs is 0) + */ + +#include "landlock_common.h" + +static struct landlock_ruleset_attr *ruleset_attr; +static struct landlock_ruleset_attr *null_attr; +static size_t rule_size; +static size_t rule_small_size; +static size_t rule_big_size; + +static struct tcase { + struct landlock_ruleset_attr **attr; + uint64_t access_fs; + size_t *size; + uint32_t flags; + int exp_errno; + char *msg; +} tcases[] = { + {&ruleset_attr, -1, &rule_size, 0, EINVAL, "Unknown access"}, + {&ruleset_attr, 0, &rule_small_size, 0, EINVAL, "Size is too small"}, + {&ruleset_attr, 0, &rule_size, -1, EINVAL, "Unknown flags"}, + {&ruleset_attr, 0, &rule_big_size, 0, E2BIG, "Size is too big"}, + {&null_attr, 0, &rule_size, 0, EFAULT, "Invalid attr address"}, + {&ruleset_attr, 0, &rule_size, 0, ENOMSG, "Empty accesses"}, +}; + +static void run(unsigned int n) +{ + struct tcase *tc = &tcases[n]; + + if (*tc->attr) + (*tc->attr)->handled_access_fs = tc->access_fs; + + TST_EXP_FAIL(tst_syscall(__NR_landlock_create_ruleset, + *tc->attr, *tc->size, tc->flags), + tc->exp_errno, + "%s", + tc->msg); + + if (TST_RET >= 0) + SAFE_CLOSE(TST_RET); +} + +static void setup(void) +{ + verify_landlock_is_enabled(); + + rule_size = sizeof(struct landlock_ruleset_attr); + +#ifdef HAVE_STRUCT_LANDLOCK_RULESET_ATTR_HANDLED_ACCESS_NET + rule_small_size = rule_size - sizeof(uint64_t);This is incorrect, at least decrease 1 more number: rule_small_size = rule_size - sizeof(uint64_t) - 1; But, those are quite unnecessary to add the if macro conditions, as the kernel code explicitly compares the minimal struct with handled_access_fs via: offsetofend(typeof(ruleset_attr), handled_access_fs) I usually don't look at the kernel source code to write tests, because for us it should be a black box that could have wrong documentation. That's also the way we find bugs. I would go for still using the macros, but removing 1 more byte from the size when handled_access_net is defined.
Okay, fine. We still have to adjust the case if someone introduces one more new field similar to 'handled_access_net' to the structure in the future.
quoted hunk ↗ jump to hunk
(and Mickael said it should never change for backward compatibility reason) So it should be just simple like:--- a/testcases/kernel/syscalls/landlock/landlock01.c +++ b/testcases/kernel/syscalls/landlock/landlock01.c@@ -62,11 +62,15 @@ static void setup(void) rule_size = sizeof(struct landlock_ruleset_attr); -#ifdef HAVE_STRUCT_LANDLOCK_RULESET_ATTR_HANDLED_ACCESS_NET - rule_small_size = rule_size - sizeof(uint64_t); -#else - rule_small_size = rule_size - 1; -#endif + /* + * The new kernel introduces a new field 'handled_access_net' inthe + * structure 'landlock_ruleset_attr'. However, in the function + * 'landlock_create_ruleset()', it still uses the first field + * 'handled_access_fs' to calculate the minimal size for backward + * compatibility reason. Therefore, here test 'sizeof(__u64) - 1' is + * sufficient to determine the minimum size for 'rule_small_size'. + */ + rule_small_size = sizeof(__u64) - 1; rule_big_size = SAFE_SYSCONF(_SC_PAGESIZE) + 1; }quoted
+#else + rule_small_size = rule_size - 1; +#endif + + rule_big_size = SAFE_SYSCONF(_SC_PAGESIZE) + 1; +} + +static struct tst_test test = { + .test = run, + .tcnt = ARRAY_SIZE(tcases), + .setup = setup, + .min_kver = "5.13", + .needs_root = 1, + .needs_kconfigs = (const char *[]) { + "CONFIG_SECURITY_LANDLOCK=y", + NULL + }, + .bufs = (struct tst_buffers []) { + {&ruleset_attr, .size = sizeof(struct landlock_ruleset_attr)}, + {}, + }, + .caps = (struct tst_cap []) { + TST_CAP(TST_CAP_REQ, CAP_SYS_ADMIN), + {} + }, +};diff --git a/testcases/kernel/syscalls/landlock/landlock_common.hb/testcases/kernel/syscalls/landlock/landlock_common.h new file mode 100644 index 000000000..66f8fd19a--- /dev/null +++ b/testcases/kernel/syscalls/landlock/landlock_common.h@@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com> + */ + +#ifndef LANDLOCK_COMMON_H + +#include "tst_test.h" +#include "lapi/prctl.h" +#include "lapi/fcntl.h" +#include "lapi/landlock.h" + +static inline void verify_landlock_is_enabled(void) +{ + int abi; + + abi = tst_syscall(__NR_landlock_create_ruleset, + NULL, 0, LANDLOCK_CREATE_RULESET_VERSION); + + if (abi < 0) { + if (errno == EOPNOTSUPP) { + tst_brk(TCONF, "Landlock is currently disabled. " + "Please enable it either via CONFIG_LSM or " + "'lsm' kernel parameter."); + } + + tst_brk(TBROK | TERRNO, "landlock_create_ruleset error"); + } + + tst_res(TINFO, "Landlock ABI v%d", abi); +} + +static inline void apply_landlock_rule( + struct landlock_path_beneath_attr *path_beneath_attr, + const int ruleset_fd, + const int access, + const char *path) +{ + path_beneath_attr->allowed_access = access; + path_beneath_attr->parent_fd = SAFE_OPEN(path, O_PATH | O_CLOEXEC); + + SAFE_LANDLOCK_ADD_RULE( + ruleset_fd, + LANDLOCK_RULE_PATH_BENEATH, + path_beneath_attr, + 0); + + SAFE_CLOSE(path_beneath_attr->parent_fd); +} + +static inline void enforce_ruleset(const int ruleset_fd) +{ + SAFE_PRCTL(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + SAFE_LANDLOCK_RESTRICT_SELF(ruleset_fd, 0); +} + +static inline void apply_landlock_layer( + struct landlock_ruleset_attr *ruleset_attr, + struct landlock_path_beneath_attr *path_beneath_attr, + const char *path, + const int access) +{ + int ruleset_fd; + + ruleset_fd = SAFE_LANDLOCK_CREATE_RULESET( + ruleset_attr, sizeof(struct landlock_ruleset_attr), 0); + + apply_landlock_rule(path_beneath_attr, ruleset_fd, access, path); + enforce_ruleset(ruleset_fd); + + SAFE_CLOSE(ruleset_fd); +} + +#endif -- 2.43.0-- Regards, Li Wang Andrea
-- Regards, Li Wang -- Mailing list info: https://lists.linux.it/listinfo/ltp