From: Greg Kroah-Hartman Date: Mon, 6 Jun 2022 13:39:28 +0000 (+0200) Subject: 5.18-stable patches X-Git-Tag: v5.10.121~88 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=623373e033baa3291faf19b5bec5789a57b4ebbc;p=thirdparty%2Fkernel%2Fstable-queue.git 5.18-stable patches added patches: landlock-add-clang-format-exceptions.patch landlock-change-landlock_add_rule-2-argument-check-ordering.patch landlock-change-landlock_restrict_self-2-check-ordering.patch landlock-create-find_rule-from-unmask_layers.patch landlock-define-access_mask_t-to-enforce-a-consistent-access-mask-size.patch landlock-fix-landlock_add_rule-2-documentation.patch landlock-fix-same-layer-rule-unions.patch landlock-format-with-clang-format.patch landlock-reduce-the-maximum-number-of-layers-to-16.patch samples-landlock-add-clang-format-exceptions.patch samples-landlock-format-with-clang-format.patch selftests-landlock-add-clang-format-exceptions.patch selftests-landlock-add-tests-for-o_path.patch selftests-landlock-add-tests-for-unknown-access-rights.patch selftests-landlock-extend-access-right-tests-to-directories.patch selftests-landlock-extend-tests-for-minimal-valid-attribute-size.patch selftests-landlock-format-with-clang-format.patch selftests-landlock-fully-test-file-rename-with-remove-access.patch selftests-landlock-make-tests-build-with-old-libc.patch selftests-landlock-normalize-array-assignment.patch selftests-landlock-test-landlock_create_ruleset-2-argument-check-ordering.patch --- diff --git a/queue-5.18/landlock-add-clang-format-exceptions.patch b/queue-5.18/landlock-add-clang-format-exceptions.patch new file mode 100644 index 00000000000..99a44acb654 --- /dev/null +++ b/queue-5.18/landlock-add-clang-format-exceptions.patch @@ -0,0 +1,86 @@ +From 6cc2df8e3a3967e7c13a424f87f6efb1d4a62d80 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:05:07 +0200 +Subject: landlock: Add clang-format exceptions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 6cc2df8e3a3967e7c13a424f87f6efb1d4a62d80 upstream. + +In preparation to a following commit, add clang-format on and +clang-format off stanzas around constant definitions. This enables to +keep aligned values, which is much more readable than packed +definitions. + +Link: https://lore.kernel.org/r/20220506160513.523257-2-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + include/uapi/linux/landlock.h | 4 ++++ + security/landlock/fs.c | 2 ++ + security/landlock/limits.h | 4 ++++ + 3 files changed, 10 insertions(+) + +--- a/include/uapi/linux/landlock.h ++++ b/include/uapi/linux/landlock.h +@@ -33,7 +33,9 @@ struct landlock_ruleset_attr { + * - %LANDLOCK_CREATE_RULESET_VERSION: Get the highest supported Landlock ABI + * version. + */ ++/* clang-format off */ + #define LANDLOCK_CREATE_RULESET_VERSION (1U << 0) ++/* clang-format on */ + + /** + * enum landlock_rule_type - Landlock rule type +@@ -120,6 +122,7 @@ struct landlock_path_beneath_attr { + * :manpage:`access(2)`. + * Future Landlock evolutions will enable to restrict them. + */ ++/* clang-format off */ + #define LANDLOCK_ACCESS_FS_EXECUTE (1ULL << 0) + #define LANDLOCK_ACCESS_FS_WRITE_FILE (1ULL << 1) + #define LANDLOCK_ACCESS_FS_READ_FILE (1ULL << 2) +@@ -133,5 +136,6 @@ struct landlock_path_beneath_attr { + #define LANDLOCK_ACCESS_FS_MAKE_FIFO (1ULL << 10) + #define LANDLOCK_ACCESS_FS_MAKE_BLOCK (1ULL << 11) + #define LANDLOCK_ACCESS_FS_MAKE_SYM (1ULL << 12) ++/* clang-format on */ + + #endif /* _UAPI_LINUX_LANDLOCK_H */ +--- a/security/landlock/fs.c ++++ b/security/landlock/fs.c +@@ -141,10 +141,12 @@ retry: + } + + /* All access rights that can be tied to files. */ ++/* clang-format off */ + #define ACCESS_FILE ( \ + LANDLOCK_ACCESS_FS_EXECUTE | \ + LANDLOCK_ACCESS_FS_WRITE_FILE | \ + LANDLOCK_ACCESS_FS_READ_FILE) ++/* clang-format on */ + + /* + * @path: Should have been checked by get_path_from_fd(). +--- a/security/landlock/limits.h ++++ b/security/landlock/limits.h +@@ -12,10 +12,14 @@ + #include + #include + ++/* clang-format off */ ++ + #define LANDLOCK_MAX_NUM_LAYERS 64 + #define LANDLOCK_MAX_NUM_RULES U32_MAX + + #define LANDLOCK_LAST_ACCESS_FS LANDLOCK_ACCESS_FS_MAKE_SYM + #define LANDLOCK_MASK_ACCESS_FS ((LANDLOCK_LAST_ACCESS_FS << 1) - 1) + ++/* clang-format on */ ++ + #endif /* _SECURITY_LANDLOCK_LIMITS_H */ diff --git a/queue-5.18/landlock-change-landlock_add_rule-2-argument-check-ordering.patch b/queue-5.18/landlock-change-landlock_add_rule-2-argument-check-ordering.patch new file mode 100644 index 00000000000..0acca80c281 --- /dev/null +++ b/queue-5.18/landlock-change-landlock_add_rule-2-argument-check-ordering.patch @@ -0,0 +1,118 @@ +From 589172e5636c4d16c40b90e87543d43defe2d968 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:08:18 +0200 +Subject: landlock: Change landlock_add_rule(2) argument check ordering +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 589172e5636c4d16c40b90e87543d43defe2d968 upstream. + +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). + +Link: https://lore.kernel.org/r/20220506160820.524344-9-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + security/landlock/syscalls.c | 22 ++++++++++------- + tools/testing/selftests/landlock/base_test.c | 34 +++++++++++++++++++++++++-- + 2 files changed, 45 insertions(+), 11 deletions(-) + +--- a/security/landlock/syscalls.c ++++ b/security/landlock/syscalls.c +@@ -318,20 +318,24 @@ SYSCALL_DEFINE4(landlock_add_rule, const + 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. +--- 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)); + } + diff --git a/queue-5.18/landlock-change-landlock_restrict_self-2-check-ordering.patch b/queue-5.18/landlock-change-landlock_restrict_self-2-check-ordering.patch new file mode 100644 index 00000000000..9879ab70bf3 --- /dev/null +++ b/queue-5.18/landlock-change-landlock_restrict_self-2-check-ordering.patch @@ -0,0 +1,115 @@ +From eba39ca4b155c54adf471a69e91799cc1727873f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:08:19 +0200 +Subject: landlock: Change landlock_restrict_self(2) check ordering +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit eba39ca4b155c54adf471a69e91799cc1727873f upstream. + +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. + +Link: https://lore.kernel.org/r/20220506160820.524344-10-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + security/landlock/syscalls.c | 8 ++-- + tools/testing/selftests/landlock/base_test.c | 47 +++++++++++++++++++++------ + 2 files changed, 41 insertions(+), 14 deletions(-) + +--- a/security/landlock/syscalls.c ++++ b/security/landlock/syscalls.c +@@ -405,10 +405,6 @@ SYSCALL_DEFINE2(landlock_restrict_self, + 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, + !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)) +--- 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) diff --git a/queue-5.18/landlock-create-find_rule-from-unmask_layers.patch b/queue-5.18/landlock-create-find_rule-from-unmask_layers.patch new file mode 100644 index 00000000000..367ee9675c7 --- /dev/null +++ b/queue-5.18/landlock-create-find_rule-from-unmask_layers.patch @@ -0,0 +1,95 @@ +From 2cd7cd6eed88b8383cfddce589afe9c0ae1d19b4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:10:53 +0200 +Subject: landlock: Create find_rule() from unmask_layers() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 2cd7cd6eed88b8383cfddce589afe9c0ae1d19b4 upstream. + +This refactoring will be useful in a following commit. + +Reviewed-by: Paul Moore +Link: https://lore.kernel.org/r/20220506161102.525323-4-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + security/landlock/fs.c | 41 ++++++++++++++++++++++++++++------------- + 1 file changed, 28 insertions(+), 13 deletions(-) + +--- a/security/landlock/fs.c ++++ b/security/landlock/fs.c +@@ -183,23 +183,36 @@ int landlock_append_fs_rule(struct landl + + /* Access-control management */ + +-static inline layer_mask_t +-unmask_layers(const struct landlock_ruleset *const domain, +- const struct path *const path, const access_mask_t access_request, +- layer_mask_t layer_mask) ++/* ++ * The lifetime of the returned rule is tied to @domain. ++ * ++ * Returns NULL if no rule is found or if @dentry is negative. ++ */ ++static inline const struct landlock_rule * ++find_rule(const struct landlock_ruleset *const domain, ++ const struct dentry *const dentry) + { + const struct landlock_rule *rule; + const struct inode *inode; +- size_t i; + +- if (d_is_negative(path->dentry)) +- /* Ignore nonexistent leafs. */ +- return layer_mask; +- inode = d_backing_inode(path->dentry); ++ /* Ignores nonexistent leafs. */ ++ if (d_is_negative(dentry)) ++ return NULL; ++ ++ inode = d_backing_inode(dentry); + rcu_read_lock(); + rule = landlock_find_rule( + domain, rcu_dereference(landlock_inode(inode)->object)); + rcu_read_unlock(); ++ return rule; ++} ++ ++static inline layer_mask_t unmask_layers(const struct landlock_rule *const rule, ++ const access_mask_t access_request, ++ layer_mask_t layer_mask) ++{ ++ size_t layer_level; ++ + if (!rule) + return layer_mask; + +@@ -210,8 +223,9 @@ unmask_layers(const struct landlock_rule + * the remaining layers for each inode, from the first added layer to + * the last one. + */ +- for (i = 0; i < rule->num_layers; i++) { +- const struct landlock_layer *const layer = &rule->layers[i]; ++ for (layer_level = 0; layer_level < rule->num_layers; layer_level++) { ++ const struct landlock_layer *const layer = ++ &rule->layers[layer_level]; + const layer_mask_t layer_bit = BIT_ULL(layer->level - 1); + + /* Checks that the layer grants access to the full request. */ +@@ -269,8 +283,9 @@ static int check_access_path(const struc + while (true) { + struct dentry *parent_dentry; + +- layer_mask = unmask_layers(domain, &walker_path, access_request, +- layer_mask); ++ layer_mask = ++ unmask_layers(find_rule(domain, walker_path.dentry), ++ access_request, layer_mask); + if (layer_mask == 0) { + /* Stops when a rule from each layer grants access. */ + allowed = true; diff --git a/queue-5.18/landlock-define-access_mask_t-to-enforce-a-consistent-access-mask-size.patch b/queue-5.18/landlock-define-access_mask_t-to-enforce-a-consistent-access-mask-size.patch new file mode 100644 index 00000000000..cfd061bbcf1 --- /dev/null +++ b/queue-5.18/landlock-define-access_mask_t-to-enforce-a-consistent-access-mask-size.patch @@ -0,0 +1,209 @@ +From 5f2ff33e10843ef51275c8611bdb7b49537aba5d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:10:51 +0200 +Subject: landlock: Define access_mask_t to enforce a consistent access mask size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 5f2ff33e10843ef51275c8611bdb7b49537aba5d upstream. + +Create and use the access_mask_t typedef to enforce a consistent access +mask size and uniformly use a 16-bits type. This will helps transition +to a 32-bits value one day. + +Add a build check to make sure all (filesystem) access rights fit in. +This will be extended with a following commit. + +Reviewed-by: Paul Moore +Link: https://lore.kernel.org/r/20220506161102.525323-2-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + security/landlock/fs.c | 19 +++++++++++-------- + security/landlock/fs.h | 2 +- + security/landlock/limits.h | 2 ++ + security/landlock/ruleset.c | 6 ++++-- + security/landlock/ruleset.h | 16 ++++++++++++---- + 5 files changed, 30 insertions(+), 15 deletions(-) + +--- a/security/landlock/fs.c ++++ b/security/landlock/fs.c +@@ -152,7 +152,8 @@ retry: + * @path: Should have been checked by get_path_from_fd(). + */ + int landlock_append_fs_rule(struct landlock_ruleset *const ruleset, +- const struct path *const path, u32 access_rights) ++ const struct path *const path, ++ access_mask_t access_rights) + { + int err; + struct landlock_object *object; +@@ -184,7 +185,8 @@ int landlock_append_fs_rule(struct landl + + static inline u64 unmask_layers(const struct landlock_ruleset *const domain, + const struct path *const path, +- const u32 access_request, u64 layer_mask) ++ const access_mask_t access_request, ++ u64 layer_mask) + { + const struct landlock_rule *rule; + const struct inode *inode; +@@ -224,7 +226,8 @@ static inline u64 unmask_layers(const st + } + + static int check_access_path(const struct landlock_ruleset *const domain, +- const struct path *const path, u32 access_request) ++ const struct path *const path, ++ const access_mask_t access_request) + { + bool allowed = false; + struct path walker_path; +@@ -309,7 +312,7 @@ jump_up: + } + + static inline int current_check_access_path(const struct path *const path, +- const u32 access_request) ++ const access_mask_t access_request) + { + const struct landlock_ruleset *const dom = + landlock_get_current_domain(); +@@ -512,7 +515,7 @@ static int hook_sb_pivotroot(const struc + + /* Path hooks */ + +-static inline u32 get_mode_access(const umode_t mode) ++static inline access_mask_t get_mode_access(const umode_t mode) + { + switch (mode & S_IFMT) { + case S_IFLNK: +@@ -565,7 +568,7 @@ static int hook_path_link(struct dentry + get_mode_access(d_backing_inode(old_dentry)->i_mode)); + } + +-static inline u32 maybe_remove(const struct dentry *const dentry) ++static inline access_mask_t maybe_remove(const struct dentry *const dentry) + { + if (d_is_negative(dentry)) + return 0; +@@ -635,9 +638,9 @@ static int hook_path_rmdir(const struct + + /* File hooks */ + +-static inline u32 get_file_access(const struct file *const file) ++static inline access_mask_t get_file_access(const struct file *const file) + { +- u32 access = 0; ++ access_mask_t access = 0; + + if (file->f_mode & FMODE_READ) { + /* A directory can only be opened in read mode. */ +--- a/security/landlock/fs.h ++++ b/security/landlock/fs.h +@@ -66,6 +66,6 @@ __init void landlock_add_fs_hooks(void); + + int landlock_append_fs_rule(struct landlock_ruleset *const ruleset, + const struct path *const path, +- u32 access_hierarchy); ++ access_mask_t access_hierarchy); + + #endif /* _SECURITY_LANDLOCK_FS_H */ +--- a/security/landlock/limits.h ++++ b/security/landlock/limits.h +@@ -9,6 +9,7 @@ + #ifndef _SECURITY_LANDLOCK_LIMITS_H + #define _SECURITY_LANDLOCK_LIMITS_H + ++#include + #include + #include + +@@ -19,6 +20,7 @@ + + #define LANDLOCK_LAST_ACCESS_FS LANDLOCK_ACCESS_FS_MAKE_SYM + #define LANDLOCK_MASK_ACCESS_FS ((LANDLOCK_LAST_ACCESS_FS << 1) - 1) ++#define LANDLOCK_NUM_ACCESS_FS __const_hweight64(LANDLOCK_MASK_ACCESS_FS) + + /* clang-format on */ + +--- a/security/landlock/ruleset.c ++++ b/security/landlock/ruleset.c +@@ -45,7 +45,8 @@ static struct landlock_ruleset *create_r + return new_ruleset; + } + +-struct landlock_ruleset *landlock_create_ruleset(const u32 fs_access_mask) ++struct landlock_ruleset * ++landlock_create_ruleset(const access_mask_t fs_access_mask) + { + struct landlock_ruleset *new_ruleset; + +@@ -228,7 +229,8 @@ static void build_check_layer(void) + + /* @ruleset must be locked by the caller. */ + int landlock_insert_rule(struct landlock_ruleset *const ruleset, +- struct landlock_object *const object, const u32 access) ++ struct landlock_object *const object, ++ const access_mask_t access) + { + struct landlock_layer layers[] = { { + .access = access, +--- a/security/landlock/ruleset.h ++++ b/security/landlock/ruleset.h +@@ -9,13 +9,20 @@ + #ifndef _SECURITY_LANDLOCK_RULESET_H + #define _SECURITY_LANDLOCK_RULESET_H + ++#include ++#include + #include + #include + #include + #include + ++#include "limits.h" + #include "object.h" + ++typedef u16 access_mask_t; ++/* Makes sure all filesystem access rights can be stored. */ ++static_assert(BITS_PER_TYPE(access_mask_t) >= LANDLOCK_NUM_ACCESS_FS); ++ + /** + * struct landlock_layer - Access rights for a given layer + */ +@@ -28,7 +35,7 @@ struct landlock_layer { + * @access: Bitfield of allowed actions on the kernel object. They are + * relative to the object type (e.g. %LANDLOCK_ACTION_FS_READ). + */ +- u16 access; ++ access_mask_t access; + }; + + /** +@@ -135,19 +142,20 @@ struct landlock_ruleset { + * layers are set once and never changed for the + * lifetime of the ruleset. + */ +- u16 fs_access_masks[]; ++ access_mask_t fs_access_masks[]; + }; + }; + }; + +-struct landlock_ruleset *landlock_create_ruleset(const u32 fs_access_mask); ++struct landlock_ruleset * ++landlock_create_ruleset(const access_mask_t fs_access_mask); + + void landlock_put_ruleset(struct landlock_ruleset *const ruleset); + void landlock_put_ruleset_deferred(struct landlock_ruleset *const ruleset); + + int landlock_insert_rule(struct landlock_ruleset *const ruleset, + struct landlock_object *const object, +- const u32 access); ++ const access_mask_t access); + + struct landlock_ruleset * + landlock_merge_ruleset(struct landlock_ruleset *const parent, diff --git a/queue-5.18/landlock-fix-landlock_add_rule-2-documentation.patch b/queue-5.18/landlock-fix-landlock_add_rule-2-documentation.patch new file mode 100644 index 00000000000..ecad48c012c --- /dev/null +++ b/queue-5.18/landlock-fix-landlock_add_rule-2-documentation.patch @@ -0,0 +1,58 @@ +From a13e248ff90e81e9322406c0e618cf2168702f4e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:08:11 +0200 +Subject: landlock: Fix landlock_add_rule(2) documentation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit a13e248ff90e81e9322406c0e618cf2168702f4e upstream. + +It is not mandatory to pass a file descriptor obtained with the O_PATH +flag. Also, replace rule's accesses with ruleset's accesses. + +Link: https://lore.kernel.org/r/20220506160820.524344-2-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + include/uapi/linux/landlock.h | 5 +++-- + security/landlock/syscalls.c | 7 +++---- + 2 files changed, 6 insertions(+), 6 deletions(-) + +--- 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; + /* +--- a/security/landlock/syscalls.c ++++ b/security/landlock/syscalls.c +@@ -292,14 +292,13 @@ out_fdput: + * + * - 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. + */ diff --git a/queue-5.18/landlock-fix-same-layer-rule-unions.patch b/queue-5.18/landlock-fix-same-layer-rule-unions.patch new file mode 100644 index 00000000000..0c931387e5b --- /dev/null +++ b/queue-5.18/landlock-fix-same-layer-rule-unions.patch @@ -0,0 +1,311 @@ +From 8ba0005ff418ec356e176b26eaa04a6ac755d05b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:10:54 +0200 +Subject: landlock: Fix same-layer rule unions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 8ba0005ff418ec356e176b26eaa04a6ac755d05b upstream. + +The original behavior was to check if the full set of requested accesses +was allowed by at least a rule of every relevant layer. This didn't +take into account requests for multiple accesses and same-layer rules +allowing the union of these accesses in a complementary way. As a +result, multiple accesses requested on a file hierarchy matching rules +that, together, allowed these accesses, but without a unique rule +allowing all of them, was illegitimately denied. This case should be +rare in practice and it can only be triggered by the path_rename or +file_open hook implementations. + +For instance, if, for the same layer, a rule allows execution +beneath /a/b and another rule allows read beneath /a, requesting access +to read and execute at the same time for /a/b should be allowed for this +layer. + +This was an inconsistency because the union of same-layer rule accesses +was already allowed if requested once at a time anyway. + +This fix changes the way allowed accesses are gathered over a path walk. +To take into account all these rule accesses, we store in a matrix all +layer granting the set of requested accesses, according to the handled +accesses. To avoid heap allocation, we use an array on the stack which +is 2*13 bytes. A following commit bringing the LANDLOCK_ACCESS_FS_REFER +access right will increase this size to reach 112 bytes (2*14*4) in case +of link or rename actions. + +Add a new layout1.layer_rule_unions test to check that accesses from +different rules pertaining to the same layer are ORed in a file +hierarchy. Also test that it is not the case for rules from different +layers. + +Reviewed-by: Paul Moore +Link: https://lore.kernel.org/r/20220506161102.525323-5-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + security/landlock/fs.c | 80 ++++++++++++++------- + security/landlock/ruleset.h | 2 + tools/testing/selftests/landlock/fs_test.c | 107 +++++++++++++++++++++++++++++ + 3 files changed, 162 insertions(+), 27 deletions(-) + +--- a/security/landlock/fs.c ++++ b/security/landlock/fs.c +@@ -207,45 +207,67 @@ find_rule(const struct landlock_ruleset + return rule; + } + +-static inline layer_mask_t unmask_layers(const struct landlock_rule *const rule, +- const access_mask_t access_request, +- layer_mask_t layer_mask) ++/* ++ * @layer_masks is read and may be updated according to the access request and ++ * the matching rule. ++ * ++ * Returns true if the request is allowed (i.e. relevant layer masks for the ++ * request are empty). ++ */ ++static inline bool ++unmask_layers(const struct landlock_rule *const rule, ++ const access_mask_t access_request, ++ layer_mask_t (*const layer_masks)[LANDLOCK_NUM_ACCESS_FS]) + { + size_t layer_level; + ++ if (!access_request || !layer_masks) ++ return true; + if (!rule) +- return layer_mask; ++ return false; + + /* + * An access is granted if, for each policy layer, at least one rule +- * encountered on the pathwalk grants the requested accesses, +- * regardless of their position in the layer stack. We must then check ++ * encountered on the pathwalk grants the requested access, ++ * regardless of its position in the layer stack. We must then check + * the remaining layers for each inode, from the first added layer to +- * the last one. ++ * the last one. When there is multiple requested accesses, for each ++ * policy layer, the full set of requested accesses may not be granted ++ * by only one rule, but by the union (binary OR) of multiple rules. ++ * E.g. /a/b + /a => /a/b + */ + for (layer_level = 0; layer_level < rule->num_layers; layer_level++) { + const struct landlock_layer *const layer = + &rule->layers[layer_level]; + const layer_mask_t layer_bit = BIT_ULL(layer->level - 1); +- +- /* Checks that the layer grants access to the full request. */ +- if ((layer->access & access_request) == access_request) { +- layer_mask &= ~layer_bit; +- +- if (layer_mask == 0) +- return layer_mask; ++ const unsigned long access_req = access_request; ++ unsigned long access_bit; ++ bool is_empty; ++ ++ /* ++ * Records in @layer_masks which layer grants access to each ++ * requested access. ++ */ ++ is_empty = true; ++ for_each_set_bit(access_bit, &access_req, ++ ARRAY_SIZE(*layer_masks)) { ++ if (layer->access & BIT_ULL(access_bit)) ++ (*layer_masks)[access_bit] &= ~layer_bit; ++ is_empty = is_empty && !(*layer_masks)[access_bit]; + } ++ if (is_empty) ++ return true; + } +- return layer_mask; ++ return false; + } + + static int check_access_path(const struct landlock_ruleset *const domain, + const struct path *const path, + const access_mask_t access_request) + { +- bool allowed = false; ++ layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = {}; ++ bool allowed = false, has_access = false; + struct path walker_path; +- layer_mask_t layer_mask; + size_t i; + + if (!access_request) +@@ -265,13 +287,20 @@ static int check_access_path(const struc + return -EACCES; + + /* Saves all layers handling a subset of requested accesses. */ +- layer_mask = 0; + for (i = 0; i < domain->num_layers; i++) { +- if (domain->fs_access_masks[i] & access_request) +- layer_mask |= BIT_ULL(i); ++ const unsigned long access_req = access_request; ++ unsigned long access_bit; ++ ++ for_each_set_bit(access_bit, &access_req, ++ ARRAY_SIZE(layer_masks)) { ++ if (domain->fs_access_masks[i] & BIT_ULL(access_bit)) { ++ layer_masks[access_bit] |= BIT_ULL(i); ++ has_access = true; ++ } ++ } + } + /* An access request not handled by the domain is allowed. */ +- if (layer_mask == 0) ++ if (!has_access) + return 0; + + walker_path = *path; +@@ -283,14 +312,11 @@ static int check_access_path(const struc + while (true) { + struct dentry *parent_dentry; + +- layer_mask = +- unmask_layers(find_rule(domain, walker_path.dentry), +- access_request, layer_mask); +- if (layer_mask == 0) { ++ allowed = unmask_layers(find_rule(domain, walker_path.dentry), ++ access_request, &layer_masks); ++ if (allowed) + /* Stops when a rule from each layer grants access. */ +- allowed = true; + break; +- } + + jump_up: + if (walker_path.dentry == walker_path.mnt->mnt_root) { +--- a/security/landlock/ruleset.h ++++ b/security/landlock/ruleset.h +@@ -22,6 +22,8 @@ + typedef u16 access_mask_t; + /* Makes sure all filesystem access rights can be stored. */ + static_assert(BITS_PER_TYPE(access_mask_t) >= LANDLOCK_NUM_ACCESS_FS); ++/* Makes sure for_each_set_bit() and for_each_clear_bit() calls are OK. */ ++static_assert(sizeof(unsigned long) >= sizeof(access_mask_t)); + + typedef u16 layer_mask_t; + /* Makes sure all layers can be checked. */ +--- a/tools/testing/selftests/landlock/fs_test.c ++++ b/tools/testing/selftests/landlock/fs_test.c +@@ -758,6 +758,113 @@ TEST_F_FORK(layout1, ruleset_overlap) + ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY)); + } + ++TEST_F_FORK(layout1, layer_rule_unions) ++{ ++ const struct rule layer1[] = { ++ { ++ .path = dir_s1d2, ++ .access = LANDLOCK_ACCESS_FS_READ_FILE, ++ }, ++ /* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */ ++ { ++ .path = dir_s1d3, ++ .access = LANDLOCK_ACCESS_FS_WRITE_FILE, ++ }, ++ {}, ++ }; ++ const struct rule layer2[] = { ++ /* Doesn't change anything from layer1. */ ++ { ++ .path = dir_s1d2, ++ .access = LANDLOCK_ACCESS_FS_READ_FILE | ++ LANDLOCK_ACCESS_FS_WRITE_FILE, ++ }, ++ {}, ++ }; ++ const struct rule layer3[] = { ++ /* Only allows write (but not read) to dir_s1d3. */ ++ { ++ .path = dir_s1d2, ++ .access = LANDLOCK_ACCESS_FS_WRITE_FILE, ++ }, ++ {}, ++ }; ++ int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer1); ++ ++ ASSERT_LE(0, ruleset_fd); ++ enforce_ruleset(_metadata, ruleset_fd); ++ ASSERT_EQ(0, close(ruleset_fd)); ++ ++ /* Checks s1d1 hierarchy with layer1. */ ++ ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY)); ++ ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY)); ++ ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR)); ++ ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); ++ ++ /* Checks s1d2 hierarchy with layer1. */ ++ ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY)); ++ ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY)); ++ ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR)); ++ ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); ++ ++ /* Checks s1d3 hierarchy with layer1. */ ++ ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY)); ++ ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY)); ++ /* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */ ++ ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR)); ++ ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); ++ ++ /* Doesn't change anything from layer1. */ ++ ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer2); ++ ASSERT_LE(0, ruleset_fd); ++ enforce_ruleset(_metadata, ruleset_fd); ++ ASSERT_EQ(0, close(ruleset_fd)); ++ ++ /* Checks s1d1 hierarchy with layer2. */ ++ ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY)); ++ ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY)); ++ ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR)); ++ ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); ++ ++ /* Checks s1d2 hierarchy with layer2. */ ++ ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY)); ++ ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY)); ++ ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR)); ++ ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); ++ ++ /* Checks s1d3 hierarchy with layer2. */ ++ ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY)); ++ ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY)); ++ /* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */ ++ ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR)); ++ ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); ++ ++ /* Only allows write (but not read) to dir_s1d3. */ ++ ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer3); ++ ASSERT_LE(0, ruleset_fd); ++ enforce_ruleset(_metadata, ruleset_fd); ++ ASSERT_EQ(0, close(ruleset_fd)); ++ ++ /* Checks s1d1 hierarchy with layer3. */ ++ ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY)); ++ ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY)); ++ ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR)); ++ ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); ++ ++ /* Checks s1d2 hierarchy with layer3. */ ++ ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDONLY)); ++ ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY)); ++ ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR)); ++ ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); ++ ++ /* Checks s1d3 hierarchy with layer3. */ ++ ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDONLY)); ++ ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY)); ++ /* dir_s1d3 should now deny READ_FILE and WRITE_FILE (O_RDWR). */ ++ ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDWR)); ++ ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); ++} ++ + TEST_F_FORK(layout1, non_overlapping_accesses) + { + const struct rule layer1[] = { diff --git a/queue-5.18/landlock-format-with-clang-format.patch b/queue-5.18/landlock-format-with-clang-format.patch new file mode 100644 index 00000000000..5324b3c3fa1 --- /dev/null +++ b/queue-5.18/landlock-format-with-clang-format.patch @@ -0,0 +1,840 @@ +From 06a1c40a09a8dded4bf0e7e3ccbda6bddcccd7c8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:05:08 +0200 +Subject: landlock: Format with clang-format +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 06a1c40a09a8dded4bf0e7e3ccbda6bddcccd7c8 upstream. + +Let's follow a consistent and documented coding style. Everything may +not be to our liking but it is better than tacit knowledge. Moreover, +this will help maintain style consistency between different developers. + +This contains only whitespace changes. + +Automatically formatted with: +clang-format-14 -i security/landlock/*.[ch] include/uapi/linux/landlock.h + +Link: https://lore.kernel.org/r/20220506160513.523257-3-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + security/landlock/cred.c | 4 +- + security/landlock/cred.h | 8 ++-- + security/landlock/fs.c | 78 +++++++++++++++++++++-------------------- + security/landlock/fs.h | 11 +++-- + security/landlock/object.c | 6 +-- + security/landlock/object.h | 6 +-- + security/landlock/ptrace.c | 10 ++--- + security/landlock/ruleset.c | 80 +++++++++++++++++++++---------------------- + security/landlock/ruleset.h | 15 ++++---- + security/landlock/syscalls.c | 60 ++++++++++++++++---------------- + 10 files changed, 142 insertions(+), 136 deletions(-) + +--- a/security/landlock/cred.c ++++ b/security/landlock/cred.c +@@ -15,7 +15,7 @@ + #include "setup.h" + + static int hook_cred_prepare(struct cred *const new, +- const struct cred *const old, const gfp_t gfp) ++ const struct cred *const old, const gfp_t gfp) + { + struct landlock_ruleset *const old_dom = landlock_cred(old)->domain; + +@@ -42,5 +42,5 @@ static struct security_hook_list landloc + __init void landlock_add_cred_hooks(void) + { + security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), +- LANDLOCK_NAME); ++ LANDLOCK_NAME); + } +--- a/security/landlock/cred.h ++++ b/security/landlock/cred.h +@@ -20,8 +20,8 @@ struct landlock_cred_security { + struct landlock_ruleset *domain; + }; + +-static inline struct landlock_cred_security *landlock_cred( +- const struct cred *cred) ++static inline struct landlock_cred_security * ++landlock_cred(const struct cred *cred) + { + return cred->security + landlock_blob_sizes.lbs_cred; + } +@@ -34,8 +34,8 @@ static inline const struct landlock_rule + /* + * The call needs to come from an RCU read-side critical section. + */ +-static inline const struct landlock_ruleset *landlock_get_task_domain( +- const struct task_struct *const task) ++static inline const struct landlock_ruleset * ++landlock_get_task_domain(const struct task_struct *const task) + { + return landlock_cred(__task_cred(task))->domain; + } +--- a/security/landlock/fs.c ++++ b/security/landlock/fs.c +@@ -152,14 +152,14 @@ retry: + * @path: Should have been checked by get_path_from_fd(). + */ + int landlock_append_fs_rule(struct landlock_ruleset *const ruleset, +- const struct path *const path, u32 access_rights) ++ const struct path *const path, u32 access_rights) + { + int err; + struct landlock_object *object; + + /* Files only get access rights that make sense. */ +- if (!d_is_dir(path->dentry) && (access_rights | ACCESS_FILE) != +- ACCESS_FILE) ++ if (!d_is_dir(path->dentry) && ++ (access_rights | ACCESS_FILE) != ACCESS_FILE) + return -EINVAL; + if (WARN_ON_ONCE(ruleset->num_layers != 1)) + return -EINVAL; +@@ -182,10 +182,9 @@ int landlock_append_fs_rule(struct landl + + /* Access-control management */ + +-static inline u64 unmask_layers( +- const struct landlock_ruleset *const domain, +- const struct path *const path, const u32 access_request, +- u64 layer_mask) ++static inline u64 unmask_layers(const struct landlock_ruleset *const domain, ++ const struct path *const path, ++ const u32 access_request, u64 layer_mask) + { + const struct landlock_rule *rule; + const struct inode *inode; +@@ -196,8 +195,8 @@ static inline u64 unmask_layers( + return layer_mask; + inode = d_backing_inode(path->dentry); + rcu_read_lock(); +- rule = landlock_find_rule(domain, +- rcu_dereference(landlock_inode(inode)->object)); ++ rule = landlock_find_rule( ++ domain, rcu_dereference(landlock_inode(inode)->object)); + rcu_read_unlock(); + if (!rule) + return layer_mask; +@@ -225,7 +224,7 @@ static inline u64 unmask_layers( + } + + static int check_access_path(const struct landlock_ruleset *const domain, +- const struct path *const path, u32 access_request) ++ const struct path *const path, u32 access_request) + { + bool allowed = false; + struct path walker_path; +@@ -245,8 +244,8 @@ static int check_access_path(const struc + * /proc//fd/ . + */ + if ((path->dentry->d_sb->s_flags & SB_NOUSER) || +- (d_is_positive(path->dentry) && +- unlikely(IS_PRIVATE(d_backing_inode(path->dentry))))) ++ (d_is_positive(path->dentry) && ++ unlikely(IS_PRIVATE(d_backing_inode(path->dentry))))) + return 0; + if (WARN_ON_ONCE(domain->num_layers < 1)) + return -EACCES; +@@ -270,8 +269,8 @@ static int check_access_path(const struc + while (true) { + struct dentry *parent_dentry; + +- layer_mask = unmask_layers(domain, &walker_path, +- access_request, layer_mask); ++ layer_mask = unmask_layers(domain, &walker_path, access_request, ++ layer_mask); + if (layer_mask == 0) { + /* Stops when a rule from each layer grants access. */ + allowed = true; +@@ -310,7 +309,7 @@ jump_up: + } + + static inline int current_check_access_path(const struct path *const path, +- const u32 access_request) ++ const u32 access_request) + { + const struct landlock_ruleset *const dom = + landlock_get_current_domain(); +@@ -438,8 +437,8 @@ static void hook_sb_delete(struct super_ + if (prev_inode) + iput(prev_inode); + /* Waits for pending iput() in release_inode(). */ +- wait_var_event(&landlock_superblock(sb)->inode_refs, !atomic_long_read( +- &landlock_superblock(sb)->inode_refs)); ++ wait_var_event(&landlock_superblock(sb)->inode_refs, ++ !atomic_long_read(&landlock_superblock(sb)->inode_refs)); + } + + /* +@@ -461,8 +460,8 @@ static void hook_sb_delete(struct super_ + * a dedicated user space option would be required (e.g. as a ruleset flag). + */ + static int hook_sb_mount(const char *const dev_name, +- const struct path *const path, const char *const type, +- const unsigned long flags, void *const data) ++ const struct path *const path, const char *const type, ++ const unsigned long flags, void *const data) + { + if (!landlock_get_current_domain()) + return 0; +@@ -470,7 +469,7 @@ static int hook_sb_mount(const char *con + } + + static int hook_move_mount(const struct path *const from_path, +- const struct path *const to_path) ++ const struct path *const to_path) + { + if (!landlock_get_current_domain()) + return 0; +@@ -504,7 +503,7 @@ static int hook_sb_remount(struct super_ + * view of the filesystem. + */ + static int hook_sb_pivotroot(const struct path *const old_path, +- const struct path *const new_path) ++ const struct path *const new_path) + { + if (!landlock_get_current_domain()) + return 0; +@@ -547,8 +546,8 @@ static inline u32 get_mode_access(const + * deal with that. + */ + static int hook_path_link(struct dentry *const old_dentry, +- const struct path *const new_dir, +- struct dentry *const new_dentry) ++ const struct path *const new_dir, ++ struct dentry *const new_dentry) + { + const struct landlock_ruleset *const dom = + landlock_get_current_domain(); +@@ -561,8 +560,9 @@ static int hook_path_link(struct dentry + return -EXDEV; + if (unlikely(d_is_negative(old_dentry))) + return -ENOENT; +- return check_access_path(dom, new_dir, +- get_mode_access(d_backing_inode(old_dentry)->i_mode)); ++ return check_access_path( ++ dom, new_dir, ++ get_mode_access(d_backing_inode(old_dentry)->i_mode)); + } + + static inline u32 maybe_remove(const struct dentry *const dentry) +@@ -570,13 +570,13 @@ static inline u32 maybe_remove(const str + if (d_is_negative(dentry)) + return 0; + return d_is_dir(dentry) ? LANDLOCK_ACCESS_FS_REMOVE_DIR : +- LANDLOCK_ACCESS_FS_REMOVE_FILE; ++ LANDLOCK_ACCESS_FS_REMOVE_FILE; + } + + static int hook_path_rename(const struct path *const old_dir, +- struct dentry *const old_dentry, +- const struct path *const new_dir, +- struct dentry *const new_dentry) ++ struct dentry *const old_dentry, ++ const struct path *const new_dir, ++ struct dentry *const new_dentry) + { + const struct landlock_ruleset *const dom = + landlock_get_current_domain(); +@@ -590,20 +590,21 @@ static int hook_path_rename(const struct + if (unlikely(d_is_negative(old_dentry))) + return -ENOENT; + /* RENAME_EXCHANGE is handled because directories are the same. */ +- return check_access_path(dom, old_dir, maybe_remove(old_dentry) | +- maybe_remove(new_dentry) | ++ return check_access_path( ++ dom, old_dir, ++ maybe_remove(old_dentry) | maybe_remove(new_dentry) | + get_mode_access(d_backing_inode(old_dentry)->i_mode)); + } + + static int hook_path_mkdir(const struct path *const dir, +- struct dentry *const dentry, const umode_t mode) ++ struct dentry *const dentry, const umode_t mode) + { + return current_check_access_path(dir, LANDLOCK_ACCESS_FS_MAKE_DIR); + } + + static int hook_path_mknod(const struct path *const dir, +- struct dentry *const dentry, const umode_t mode, +- const unsigned int dev) ++ struct dentry *const dentry, const umode_t mode, ++ const unsigned int dev) + { + const struct landlock_ruleset *const dom = + landlock_get_current_domain(); +@@ -614,19 +615,20 @@ static int hook_path_mknod(const struct + } + + static int hook_path_symlink(const struct path *const dir, +- struct dentry *const dentry, const char *const old_name) ++ struct dentry *const dentry, ++ const char *const old_name) + { + return current_check_access_path(dir, LANDLOCK_ACCESS_FS_MAKE_SYM); + } + + static int hook_path_unlink(const struct path *const dir, +- struct dentry *const dentry) ++ struct dentry *const dentry) + { + return current_check_access_path(dir, LANDLOCK_ACCESS_FS_REMOVE_FILE); + } + + static int hook_path_rmdir(const struct path *const dir, +- struct dentry *const dentry) ++ struct dentry *const dentry) + { + return current_check_access_path(dir, LANDLOCK_ACCESS_FS_REMOVE_DIR); + } +@@ -690,5 +692,5 @@ static struct security_hook_list landloc + __init void landlock_add_fs_hooks(void) + { + security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), +- LANDLOCK_NAME); ++ LANDLOCK_NAME); + } +--- a/security/landlock/fs.h ++++ b/security/landlock/fs.h +@@ -50,14 +50,14 @@ struct landlock_superblock_security { + atomic_long_t inode_refs; + }; + +-static inline struct landlock_inode_security *landlock_inode( +- const struct inode *const inode) ++static inline struct landlock_inode_security * ++landlock_inode(const struct inode *const inode) + { + return inode->i_security + landlock_blob_sizes.lbs_inode; + } + +-static inline struct landlock_superblock_security *landlock_superblock( +- const struct super_block *const superblock) ++static inline struct landlock_superblock_security * ++landlock_superblock(const struct super_block *const superblock) + { + return superblock->s_security + landlock_blob_sizes.lbs_superblock; + } +@@ -65,6 +65,7 @@ static inline struct landlock_superblock + __init void landlock_add_fs_hooks(void); + + int landlock_append_fs_rule(struct landlock_ruleset *const ruleset, +- const struct path *const path, u32 access_hierarchy); ++ const struct path *const path, ++ u32 access_hierarchy); + + #endif /* _SECURITY_LANDLOCK_FS_H */ +--- a/security/landlock/object.c ++++ b/security/landlock/object.c +@@ -17,9 +17,9 @@ + + #include "object.h" + +-struct landlock_object *landlock_create_object( +- const struct landlock_object_underops *const underops, +- void *const underobj) ++struct landlock_object * ++landlock_create_object(const struct landlock_object_underops *const underops, ++ void *const underobj) + { + struct landlock_object *new_object; + +--- a/security/landlock/object.h ++++ b/security/landlock/object.h +@@ -76,9 +76,9 @@ struct landlock_object { + }; + }; + +-struct landlock_object *landlock_create_object( +- const struct landlock_object_underops *const underops, +- void *const underobj); ++struct landlock_object * ++landlock_create_object(const struct landlock_object_underops *const underops, ++ void *const underobj); + + void landlock_put_object(struct landlock_object *const object); + +--- a/security/landlock/ptrace.c ++++ b/security/landlock/ptrace.c +@@ -30,7 +30,7 @@ + * means a subset of) the @child domain. + */ + static bool domain_scope_le(const struct landlock_ruleset *const parent, +- const struct landlock_ruleset *const child) ++ const struct landlock_ruleset *const child) + { + const struct landlock_hierarchy *walker; + +@@ -48,7 +48,7 @@ static bool domain_scope_le(const struct + } + + static bool task_is_scoped(const struct task_struct *const parent, +- const struct task_struct *const child) ++ const struct task_struct *const child) + { + bool is_scoped; + const struct landlock_ruleset *dom_parent, *dom_child; +@@ -62,7 +62,7 @@ static bool task_is_scoped(const struct + } + + static int task_ptrace(const struct task_struct *const parent, +- const struct task_struct *const child) ++ const struct task_struct *const child) + { + /* Quick return for non-landlocked tasks. */ + if (!landlocked(parent)) +@@ -86,7 +86,7 @@ static int task_ptrace(const struct task + * granted, -errno if denied. + */ + static int hook_ptrace_access_check(struct task_struct *const child, +- const unsigned int mode) ++ const unsigned int mode) + { + return task_ptrace(current, child); + } +@@ -116,5 +116,5 @@ static struct security_hook_list landloc + __init void landlock_add_ptrace_hooks(void) + { + security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), +- LANDLOCK_NAME); ++ LANDLOCK_NAME); + } +--- a/security/landlock/ruleset.c ++++ b/security/landlock/ruleset.c +@@ -28,8 +28,9 @@ static struct landlock_ruleset *create_r + { + struct landlock_ruleset *new_ruleset; + +- new_ruleset = kzalloc(struct_size(new_ruleset, fs_access_masks, +- num_layers), GFP_KERNEL_ACCOUNT); ++ new_ruleset = ++ kzalloc(struct_size(new_ruleset, fs_access_masks, num_layers), ++ GFP_KERNEL_ACCOUNT); + if (!new_ruleset) + return ERR_PTR(-ENOMEM); + refcount_set(&new_ruleset->usage, 1); +@@ -66,11 +67,10 @@ static void build_check_rule(void) + BUILD_BUG_ON(rule.num_layers < LANDLOCK_MAX_NUM_LAYERS); + } + +-static struct landlock_rule *create_rule( +- struct landlock_object *const object, +- const struct landlock_layer (*const layers)[], +- const u32 num_layers, +- const struct landlock_layer *const new_layer) ++static struct landlock_rule * ++create_rule(struct landlock_object *const object, ++ const struct landlock_layer (*const layers)[], const u32 num_layers, ++ const struct landlock_layer *const new_layer) + { + struct landlock_rule *new_rule; + u32 new_num_layers; +@@ -85,7 +85,7 @@ static struct landlock_rule *create_rule + new_num_layers = num_layers; + } + new_rule = kzalloc(struct_size(new_rule, layers, new_num_layers), +- GFP_KERNEL_ACCOUNT); ++ GFP_KERNEL_ACCOUNT); + if (!new_rule) + return ERR_PTR(-ENOMEM); + RB_CLEAR_NODE(&new_rule->node); +@@ -94,7 +94,7 @@ static struct landlock_rule *create_rule + new_rule->num_layers = new_num_layers; + /* Copies the original layer stack. */ + memcpy(new_rule->layers, layers, +- flex_array_size(new_rule, layers, num_layers)); ++ flex_array_size(new_rule, layers, num_layers)); + if (new_layer) + /* Adds a copy of @new_layer on the layer stack. */ + new_rule->layers[new_rule->num_layers - 1] = *new_layer; +@@ -142,9 +142,9 @@ static void build_check_ruleset(void) + * access rights. + */ + static int insert_rule(struct landlock_ruleset *const ruleset, +- struct landlock_object *const object, +- const struct landlock_layer (*const layers)[], +- size_t num_layers) ++ struct landlock_object *const object, ++ const struct landlock_layer (*const layers)[], ++ size_t num_layers) + { + struct rb_node **walker_node; + struct rb_node *parent_node = NULL; +@@ -156,8 +156,8 @@ static int insert_rule(struct landlock_r + return -ENOENT; + walker_node = &(ruleset->root.rb_node); + while (*walker_node) { +- struct landlock_rule *const this = rb_entry(*walker_node, +- struct landlock_rule, node); ++ struct landlock_rule *const this = ++ rb_entry(*walker_node, struct landlock_rule, node); + + if (this->object != object) { + parent_node = *walker_node; +@@ -194,7 +194,7 @@ static int insert_rule(struct landlock_r + * ruleset and a domain. + */ + new_rule = create_rule(object, &this->layers, this->num_layers, +- &(*layers)[0]); ++ &(*layers)[0]); + if (IS_ERR(new_rule)) + return PTR_ERR(new_rule); + rb_replace_node(&this->node, &new_rule->node, &ruleset->root); +@@ -228,13 +228,13 @@ static void build_check_layer(void) + + /* @ruleset must be locked by the caller. */ + int landlock_insert_rule(struct landlock_ruleset *const ruleset, +- struct landlock_object *const object, const u32 access) ++ struct landlock_object *const object, const u32 access) + { +- struct landlock_layer layers[] = {{ ++ struct landlock_layer layers[] = { { + .access = access, + /* When @level is zero, insert_rule() extends @ruleset. */ + .level = 0, +- }}; ++ } }; + + build_check_layer(); + return insert_rule(ruleset, object, &layers, ARRAY_SIZE(layers)); +@@ -257,7 +257,7 @@ static void put_hierarchy(struct landloc + } + + static int merge_ruleset(struct landlock_ruleset *const dst, +- struct landlock_ruleset *const src) ++ struct landlock_ruleset *const src) + { + struct landlock_rule *walker_rule, *next_rule; + int err = 0; +@@ -282,11 +282,11 @@ static int merge_ruleset(struct landlock + dst->fs_access_masks[dst->num_layers - 1] = src->fs_access_masks[0]; + + /* Merges the @src tree. */ +- rbtree_postorder_for_each_entry_safe(walker_rule, next_rule, +- &src->root, node) { +- struct landlock_layer layers[] = {{ ++ rbtree_postorder_for_each_entry_safe(walker_rule, next_rule, &src->root, ++ node) { ++ struct landlock_layer layers[] = { { + .level = dst->num_layers, +- }}; ++ } }; + + if (WARN_ON_ONCE(walker_rule->num_layers != 1)) { + err = -EINVAL; +@@ -298,7 +298,7 @@ static int merge_ruleset(struct landlock + } + layers[0].access = walker_rule->layers[0].access; + err = insert_rule(dst, walker_rule->object, &layers, +- ARRAY_SIZE(layers)); ++ ARRAY_SIZE(layers)); + if (err) + goto out_unlock; + } +@@ -310,7 +310,7 @@ out_unlock: + } + + static int inherit_ruleset(struct landlock_ruleset *const parent, +- struct landlock_ruleset *const child) ++ struct landlock_ruleset *const child) + { + struct landlock_rule *walker_rule, *next_rule; + int err = 0; +@@ -325,9 +325,10 @@ static int inherit_ruleset(struct landlo + + /* Copies the @parent tree. */ + rbtree_postorder_for_each_entry_safe(walker_rule, next_rule, +- &parent->root, node) { ++ &parent->root, node) { + err = insert_rule(child, walker_rule->object, +- &walker_rule->layers, walker_rule->num_layers); ++ &walker_rule->layers, ++ walker_rule->num_layers); + if (err) + goto out_unlock; + } +@@ -338,7 +339,7 @@ static int inherit_ruleset(struct landlo + } + /* Copies the parent layer stack and leaves a space for the new layer. */ + memcpy(child->fs_access_masks, parent->fs_access_masks, +- flex_array_size(parent, fs_access_masks, parent->num_layers)); ++ flex_array_size(parent, fs_access_masks, parent->num_layers)); + + if (WARN_ON_ONCE(!parent->hierarchy)) { + err = -EINVAL; +@@ -358,8 +359,7 @@ static void free_ruleset(struct landlock + struct landlock_rule *freeme, *next; + + might_sleep(); +- rbtree_postorder_for_each_entry_safe(freeme, next, &ruleset->root, +- node) ++ rbtree_postorder_for_each_entry_safe(freeme, next, &ruleset->root, node) + free_rule(freeme); + put_hierarchy(ruleset->hierarchy); + kfree(ruleset); +@@ -397,9 +397,9 @@ void landlock_put_ruleset_deferred(struc + * Returns the intersection of @parent and @ruleset, or returns @parent if + * @ruleset is empty, or returns a duplicate of @ruleset if @parent is empty. + */ +-struct landlock_ruleset *landlock_merge_ruleset( +- struct landlock_ruleset *const parent, +- struct landlock_ruleset *const ruleset) ++struct landlock_ruleset * ++landlock_merge_ruleset(struct landlock_ruleset *const parent, ++ struct landlock_ruleset *const ruleset) + { + struct landlock_ruleset *new_dom; + u32 num_layers; +@@ -421,8 +421,8 @@ struct landlock_ruleset *landlock_merge_ + new_dom = create_ruleset(num_layers); + if (IS_ERR(new_dom)) + return new_dom; +- new_dom->hierarchy = kzalloc(sizeof(*new_dom->hierarchy), +- GFP_KERNEL_ACCOUNT); ++ new_dom->hierarchy = ++ kzalloc(sizeof(*new_dom->hierarchy), GFP_KERNEL_ACCOUNT); + if (!new_dom->hierarchy) { + err = -ENOMEM; + goto out_put_dom; +@@ -449,9 +449,9 @@ out_put_dom: + /* + * The returned access has the same lifetime as @ruleset. + */ +-const struct landlock_rule *landlock_find_rule( +- const struct landlock_ruleset *const ruleset, +- const struct landlock_object *const object) ++const struct landlock_rule * ++landlock_find_rule(const struct landlock_ruleset *const ruleset, ++ const struct landlock_object *const object) + { + const struct rb_node *node; + +@@ -459,8 +459,8 @@ const struct landlock_rule *landlock_fin + return NULL; + node = ruleset->root.rb_node; + while (node) { +- struct landlock_rule *this = rb_entry(node, +- struct landlock_rule, node); ++ struct landlock_rule *this = ++ rb_entry(node, struct landlock_rule, node); + + if (this->object == object) + return this; +--- a/security/landlock/ruleset.h ++++ b/security/landlock/ruleset.h +@@ -146,15 +146,16 @@ void landlock_put_ruleset(struct landloc + void landlock_put_ruleset_deferred(struct landlock_ruleset *const ruleset); + + int landlock_insert_rule(struct landlock_ruleset *const ruleset, +- struct landlock_object *const object, const u32 access); ++ struct landlock_object *const object, ++ const u32 access); + +-struct landlock_ruleset *landlock_merge_ruleset( +- struct landlock_ruleset *const parent, +- struct landlock_ruleset *const ruleset); ++struct landlock_ruleset * ++landlock_merge_ruleset(struct landlock_ruleset *const parent, ++ struct landlock_ruleset *const ruleset); + +-const struct landlock_rule *landlock_find_rule( +- const struct landlock_ruleset *const ruleset, +- const struct landlock_object *const object); ++const struct landlock_rule * ++landlock_find_rule(const struct landlock_ruleset *const ruleset, ++ const struct landlock_object *const object); + + static inline void landlock_get_ruleset(struct landlock_ruleset *const ruleset) + { +--- a/security/landlock/syscalls.c ++++ b/security/landlock/syscalls.c +@@ -43,9 +43,10 @@ + * @src: User space pointer or NULL. + * @usize: (Alleged) size of the data pointed to by @src. + */ +-static __always_inline int copy_min_struct_from_user(void *const dst, +- const size_t ksize, const size_t ksize_min, +- const void __user *const src, const size_t usize) ++static __always_inline int ++copy_min_struct_from_user(void *const dst, const size_t ksize, ++ const size_t ksize_min, const void __user *const src, ++ const size_t usize) + { + /* Checks buffer inconsistencies. */ + BUILD_BUG_ON(!dst); +@@ -93,7 +94,7 @@ static void build_check_abi(void) + /* Ruleset handling */ + + static int fop_ruleset_release(struct inode *const inode, +- struct file *const filp) ++ struct file *const filp) + { + struct landlock_ruleset *ruleset = filp->private_data; + +@@ -102,15 +103,15 @@ static int fop_ruleset_release(struct in + } + + static ssize_t fop_dummy_read(struct file *const filp, char __user *const buf, +- const size_t size, loff_t *const ppos) ++ const size_t size, loff_t *const ppos) + { + /* Dummy handler to enable FMODE_CAN_READ. */ + return -EINVAL; + } + + static ssize_t fop_dummy_write(struct file *const filp, +- const char __user *const buf, const size_t size, +- loff_t *const ppos) ++ const char __user *const buf, const size_t size, ++ loff_t *const ppos) + { + /* Dummy handler to enable FMODE_CAN_WRITE. */ + return -EINVAL; +@@ -128,7 +129,7 @@ static const struct file_operations rule + .write = fop_dummy_write, + }; + +-#define LANDLOCK_ABI_VERSION 1 ++#define LANDLOCK_ABI_VERSION 1 + + /** + * sys_landlock_create_ruleset - Create a new ruleset +@@ -168,22 +169,23 @@ SYSCALL_DEFINE3(landlock_create_ruleset, + return -EOPNOTSUPP; + + if (flags) { +- if ((flags == LANDLOCK_CREATE_RULESET_VERSION) +- && !attr && !size) ++ if ((flags == LANDLOCK_CREATE_RULESET_VERSION) && !attr && ++ !size) + return LANDLOCK_ABI_VERSION; + return -EINVAL; + } + + /* Copies raw user space buffer. */ + err = copy_min_struct_from_user(&ruleset_attr, sizeof(ruleset_attr), +- offsetofend(typeof(ruleset_attr), handled_access_fs), +- attr, size); ++ offsetofend(typeof(ruleset_attr), ++ handled_access_fs), ++ attr, size); + if (err) + return err; + + /* Checks content (and 32-bits cast). */ + if ((ruleset_attr.handled_access_fs | LANDLOCK_MASK_ACCESS_FS) != +- LANDLOCK_MASK_ACCESS_FS) ++ LANDLOCK_MASK_ACCESS_FS) + return -EINVAL; + + /* Checks arguments and transforms to kernel struct. */ +@@ -193,7 +195,7 @@ SYSCALL_DEFINE3(landlock_create_ruleset, + + /* Creates anonymous FD referring to the ruleset. */ + ruleset_fd = anon_inode_getfd("[landlock-ruleset]", &ruleset_fops, +- ruleset, O_RDWR | O_CLOEXEC); ++ ruleset, O_RDWR | O_CLOEXEC); + if (ruleset_fd < 0) + landlock_put_ruleset(ruleset); + return ruleset_fd; +@@ -204,7 +206,7 @@ SYSCALL_DEFINE3(landlock_create_ruleset, + * landlock_put_ruleset() on the return value. + */ + static struct landlock_ruleset *get_ruleset_from_fd(const int fd, +- const fmode_t mode) ++ const fmode_t mode) + { + struct fd ruleset_f; + struct landlock_ruleset *ruleset; +@@ -244,8 +246,8 @@ static int get_path_from_fd(const s32 fd + struct fd f; + int err = 0; + +- BUILD_BUG_ON(!__same_type(fd, +- ((struct landlock_path_beneath_attr *)NULL)->parent_fd)); ++ BUILD_BUG_ON(!__same_type( ++ fd, ((struct landlock_path_beneath_attr *)NULL)->parent_fd)); + + /* Handles O_PATH. */ + f = fdget_raw(fd); +@@ -257,10 +259,10 @@ static int get_path_from_fd(const s32 fd + * pipefs). + */ + if ((f.file->f_op == &ruleset_fops) || +- (f.file->f_path.mnt->mnt_flags & MNT_INTERNAL) || +- (f.file->f_path.dentry->d_sb->s_flags & SB_NOUSER) || +- d_is_negative(f.file->f_path.dentry) || +- IS_PRIVATE(d_backing_inode(f.file->f_path.dentry))) { ++ (f.file->f_path.mnt->mnt_flags & MNT_INTERNAL) || ++ (f.file->f_path.dentry->d_sb->s_flags & SB_NOUSER) || ++ d_is_negative(f.file->f_path.dentry) || ++ IS_PRIVATE(d_backing_inode(f.file->f_path.dentry))) { + err = -EBADFD; + goto out_fdput; + } +@@ -301,8 +303,8 @@ out_fdput: + * - EPERM: @ruleset_fd has no write access to the underlying ruleset; + * - EFAULT: @rule_attr inconsistency. + */ +-SYSCALL_DEFINE4(landlock_add_rule, +- const int, ruleset_fd, const enum landlock_rule_type, rule_type, ++SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd, ++ const enum landlock_rule_type, rule_type, + const void __user *const, rule_attr, const __u32, flags) + { + struct landlock_path_beneath_attr path_beneath_attr; +@@ -322,7 +324,7 @@ SYSCALL_DEFINE4(landlock_add_rule, + + /* Copies raw user space buffer, only one type for now. */ + res = copy_from_user(&path_beneath_attr, rule_attr, +- sizeof(path_beneath_attr)); ++ sizeof(path_beneath_attr)); + if (res) + return -EFAULT; + +@@ -344,7 +346,7 @@ SYSCALL_DEFINE4(landlock_add_rule, + * (ruleset->fs_access_masks[0] is automatically upgraded to 64-bits). + */ + if ((path_beneath_attr.allowed_access | ruleset->fs_access_masks[0]) != +- ruleset->fs_access_masks[0]) { ++ ruleset->fs_access_masks[0]) { + err = -EINVAL; + goto out_put_ruleset; + } +@@ -356,7 +358,7 @@ SYSCALL_DEFINE4(landlock_add_rule, + + /* Imports the new rule. */ + err = landlock_append_fs_rule(ruleset, &path, +- path_beneath_attr.allowed_access); ++ path_beneath_attr.allowed_access); + path_put(&path); + + out_put_ruleset: +@@ -389,8 +391,8 @@ out_put_ruleset: + * - E2BIG: The maximum number of stacked rulesets is reached for the current + * thread. + */ +-SYSCALL_DEFINE2(landlock_restrict_self, +- const int, ruleset_fd, const __u32, flags) ++SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32, ++ flags) + { + struct landlock_ruleset *new_dom, *ruleset; + struct cred *new_cred; +@@ -409,7 +411,7 @@ SYSCALL_DEFINE2(landlock_restrict_self, + * returned. + */ + if (!task_no_new_privs(current) && +- !ns_capable_noaudit(current_user_ns(), CAP_SYS_ADMIN)) ++ !ns_capable_noaudit(current_user_ns(), CAP_SYS_ADMIN)) + return -EPERM; + + /* Gets and checks the ruleset. */ diff --git a/queue-5.18/landlock-reduce-the-maximum-number-of-layers-to-16.patch b/queue-5.18/landlock-reduce-the-maximum-number-of-layers-to-16.patch new file mode 100644 index 00000000000..28238c9111a --- /dev/null +++ b/queue-5.18/landlock-reduce-the-maximum-number-of-layers-to-16.patch @@ -0,0 +1,129 @@ +From 75c542d6c6cc48720376862d5496d51509160dfd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:10:52 +0200 +Subject: landlock: Reduce the maximum number of layers to 16 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 75c542d6c6cc48720376862d5496d51509160dfd upstream. + +The maximum number of nested Landlock domains is currently 64. Because +of the following fix and to help reduce the stack size, let's reduce it +to 16. This seems large enough for a lot of use cases (e.g. sandboxed +init service, spawning a sandboxed SSH service, in nested sandboxed +containers). Reducing the number of nested domains may also help to +discover misuse of Landlock (e.g. creating a domain per rule). + +Add and use a dedicated layer_mask_t typedef to fit with the number of +layers. This might be useful when changing it and to keep it consistent +with the maximum number of layers. + +Reviewed-by: Paul Moore +Link: https://lore.kernel.org/r/20220506161102.525323-3-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/userspace-api/landlock.rst | 4 ++-- + security/landlock/fs.c | 17 +++++++---------- + security/landlock/limits.h | 2 +- + security/landlock/ruleset.h | 4 ++++ + tools/testing/selftests/landlock/fs_test.c | 2 +- + 5 files changed, 15 insertions(+), 14 deletions(-) + +--- a/Documentation/userspace-api/landlock.rst ++++ b/Documentation/userspace-api/landlock.rst +@@ -267,8 +267,8 @@ restrict such paths with dedicated rules + Ruleset layers + -------------- + +-There is a limit of 64 layers of stacked rulesets. This can be an issue for a +-task willing to enforce a new ruleset in complement to its 64 inherited ++There is a limit of 16 layers of stacked rulesets. This can be an issue for a ++task willing to enforce a new ruleset in complement to its 16 inherited + rulesets. Once this limit is reached, sys_landlock_restrict_self() returns + E2BIG. It is then strongly suggested to carefully build rulesets once in the + life of a thread, especially for applications able to launch other applications +--- a/security/landlock/fs.c ++++ b/security/landlock/fs.c +@@ -183,10 +183,10 @@ int landlock_append_fs_rule(struct landl + + /* Access-control management */ + +-static inline u64 unmask_layers(const struct landlock_ruleset *const domain, +- const struct path *const path, +- const access_mask_t access_request, +- u64 layer_mask) ++static inline layer_mask_t ++unmask_layers(const struct landlock_ruleset *const domain, ++ const struct path *const path, const access_mask_t access_request, ++ layer_mask_t layer_mask) + { + const struct landlock_rule *rule; + const struct inode *inode; +@@ -212,11 +212,11 @@ static inline u64 unmask_layers(const st + */ + for (i = 0; i < rule->num_layers; i++) { + const struct landlock_layer *const layer = &rule->layers[i]; +- const u64 layer_level = BIT_ULL(layer->level - 1); ++ const layer_mask_t layer_bit = BIT_ULL(layer->level - 1); + + /* Checks that the layer grants access to the full request. */ + if ((layer->access & access_request) == access_request) { +- layer_mask &= ~layer_level; ++ layer_mask &= ~layer_bit; + + if (layer_mask == 0) + return layer_mask; +@@ -231,12 +231,9 @@ static int check_access_path(const struc + { + bool allowed = false; + struct path walker_path; +- u64 layer_mask; ++ layer_mask_t layer_mask; + size_t i; + +- /* Make sure all layers can be checked. */ +- BUILD_BUG_ON(BITS_PER_TYPE(layer_mask) < LANDLOCK_MAX_NUM_LAYERS); +- + if (!access_request) + return 0; + if (WARN_ON_ONCE(!domain || !path)) +--- a/security/landlock/limits.h ++++ b/security/landlock/limits.h +@@ -15,7 +15,7 @@ + + /* clang-format off */ + +-#define LANDLOCK_MAX_NUM_LAYERS 64 ++#define LANDLOCK_MAX_NUM_LAYERS 16 + #define LANDLOCK_MAX_NUM_RULES U32_MAX + + #define LANDLOCK_LAST_ACCESS_FS LANDLOCK_ACCESS_FS_MAKE_SYM +--- a/security/landlock/ruleset.h ++++ b/security/landlock/ruleset.h +@@ -23,6 +23,10 @@ typedef u16 access_mask_t; + /* Makes sure all filesystem access rights can be stored. */ + static_assert(BITS_PER_TYPE(access_mask_t) >= LANDLOCK_NUM_ACCESS_FS); + ++typedef u16 layer_mask_t; ++/* Makes sure all layers can be checked. */ ++static_assert(BITS_PER_TYPE(layer_mask_t) >= LANDLOCK_MAX_NUM_LAYERS); ++ + /** + * struct landlock_layer - Access rights for a given layer + */ +--- a/tools/testing/selftests/landlock/fs_test.c ++++ b/tools/testing/selftests/landlock/fs_test.c +@@ -1159,7 +1159,7 @@ TEST_F_FORK(layout1, max_layers) + const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules); + + ASSERT_LE(0, ruleset_fd); +- for (i = 0; i < 64; i++) ++ for (i = 0; i < 16; i++) + enforce_ruleset(_metadata, ruleset_fd); + + for (i = 0; i < 2; i++) { diff --git a/queue-5.18/samples-landlock-add-clang-format-exceptions.patch b/queue-5.18/samples-landlock-add-clang-format-exceptions.patch new file mode 100644 index 00000000000..d8b99b937ea --- /dev/null +++ b/queue-5.18/samples-landlock-add-clang-format-exceptions.patch @@ -0,0 +1,61 @@ +From 9805a722db071e1772b80e6e0ff33f35355639ac Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:05:12 +0200 +Subject: samples/landlock: Add clang-format exceptions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 9805a722db071e1772b80e6e0ff33f35355639ac upstream. + +In preparation to a following commit, add clang-format on and +clang-format off stanzas around constant definitions. This enables to +keep aligned values, which is much more readable than packed +definitions. + +Link: https://lore.kernel.org/r/20220506160513.523257-7-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + samples/landlock/sandboxer.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/samples/landlock/sandboxer.c ++++ b/samples/landlock/sandboxer.c +@@ -70,11 +70,15 @@ static int parse_path(char *env_path, co + return num_paths; + } + ++/* clang-format off */ ++ + #define ACCESS_FILE ( \ + LANDLOCK_ACCESS_FS_EXECUTE | \ + LANDLOCK_ACCESS_FS_WRITE_FILE | \ + LANDLOCK_ACCESS_FS_READ_FILE) + ++/* clang-format on */ ++ + static int populate_ruleset( + const char *const env_var, const int ruleset_fd, + const __u64 allowed_access) +@@ -139,6 +143,8 @@ out_free_name: + return ret; + } + ++/* clang-format off */ ++ + #define ACCESS_FS_ROUGHLY_READ ( \ + LANDLOCK_ACCESS_FS_EXECUTE | \ + LANDLOCK_ACCESS_FS_READ_FILE | \ +@@ -156,6 +162,8 @@ out_free_name: + LANDLOCK_ACCESS_FS_MAKE_BLOCK | \ + LANDLOCK_ACCESS_FS_MAKE_SYM) + ++/* clang-format on */ ++ + int main(const int argc, char *const argv[], char *const *const envp) + { + const char *cmd_path; diff --git a/queue-5.18/samples-landlock-format-with-clang-format.patch b/queue-5.18/samples-landlock-format-with-clang-format.patch new file mode 100644 index 00000000000..2133d874842 --- /dev/null +++ b/queue-5.18/samples-landlock-format-with-clang-format.patch @@ -0,0 +1,208 @@ +From 81709f3dccacf4104a4bc2daa80bdd767a9c4c54 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:05:13 +0200 +Subject: samples/landlock: Format with clang-format +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 81709f3dccacf4104a4bc2daa80bdd767a9c4c54 upstream. + +Let's follow a consistent and documented coding style. Everything may +not be to our liking but it is better than tacit knowledge. Moreover, +this will help maintain style consistency between different developers. + +This contains only whitespace changes. + +Automatically formatted with: +clang-format-14 -i samples/landlock/*.[ch] + +Link: https://lore.kernel.org/r/20220506160513.523257-8-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + samples/landlock/sandboxer.c | 96 +++++++++++++++++++++++-------------------- + 1 file changed, 52 insertions(+), 44 deletions(-) + +--- a/samples/landlock/sandboxer.c ++++ b/samples/landlock/sandboxer.c +@@ -22,9 +22,9 @@ + #include + + #ifndef landlock_create_ruleset +-static inline int landlock_create_ruleset( +- const struct landlock_ruleset_attr *const attr, +- const size_t size, const __u32 flags) ++static inline int ++landlock_create_ruleset(const struct landlock_ruleset_attr *const attr, ++ const size_t size, const __u32 flags) + { + return syscall(__NR_landlock_create_ruleset, attr, size, flags); + } +@@ -32,17 +32,18 @@ static inline int landlock_create_rulese + + #ifndef landlock_add_rule + static inline int landlock_add_rule(const int ruleset_fd, +- const enum landlock_rule_type rule_type, +- const void *const rule_attr, const __u32 flags) ++ const enum landlock_rule_type rule_type, ++ const void *const rule_attr, ++ const __u32 flags) + { +- return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, +- rule_attr, flags); ++ return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, rule_attr, ++ flags); + } + #endif + + #ifndef landlock_restrict_self + static inline int landlock_restrict_self(const int ruleset_fd, +- const __u32 flags) ++ const __u32 flags) + { + return syscall(__NR_landlock_restrict_self, ruleset_fd, flags); + } +@@ -79,9 +80,8 @@ static int parse_path(char *env_path, co + + /* clang-format on */ + +-static int populate_ruleset( +- const char *const env_var, const int ruleset_fd, +- const __u64 allowed_access) ++static int populate_ruleset(const char *const env_var, const int ruleset_fd, ++ const __u64 allowed_access) + { + int num_paths, i, ret = 1; + char *env_path_name; +@@ -111,12 +111,10 @@ static int populate_ruleset( + for (i = 0; i < num_paths; i++) { + struct stat statbuf; + +- path_beneath.parent_fd = open(path_list[i], O_PATH | +- O_CLOEXEC); ++ path_beneath.parent_fd = open(path_list[i], O_PATH | O_CLOEXEC); + if (path_beneath.parent_fd < 0) { + fprintf(stderr, "Failed to open \"%s\": %s\n", +- path_list[i], +- strerror(errno)); ++ path_list[i], strerror(errno)); + goto out_free_name; + } + if (fstat(path_beneath.parent_fd, &statbuf)) { +@@ -127,9 +125,10 @@ static int populate_ruleset( + if (!S_ISDIR(statbuf.st_mode)) + path_beneath.allowed_access &= ACCESS_FILE; + if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, +- &path_beneath, 0)) { +- fprintf(stderr, "Failed to update the ruleset with \"%s\": %s\n", +- path_list[i], strerror(errno)); ++ &path_beneath, 0)) { ++ fprintf(stderr, ++ "Failed to update the ruleset with \"%s\": %s\n", ++ path_list[i], strerror(errno)); + close(path_beneath.parent_fd); + goto out_free_name; + } +@@ -171,55 +170,64 @@ int main(const int argc, char *const arg + int ruleset_fd; + struct landlock_ruleset_attr ruleset_attr = { + .handled_access_fs = ACCESS_FS_ROUGHLY_READ | +- ACCESS_FS_ROUGHLY_WRITE, ++ ACCESS_FS_ROUGHLY_WRITE, + }; + + if (argc < 2) { +- fprintf(stderr, "usage: %s=\"...\" %s=\"...\" %s [args]...\n\n", +- ENV_FS_RO_NAME, ENV_FS_RW_NAME, argv[0]); +- fprintf(stderr, "Launch a command in a restricted environment.\n\n"); ++ fprintf(stderr, ++ "usage: %s=\"...\" %s=\"...\" %s [args]...\n\n", ++ ENV_FS_RO_NAME, ENV_FS_RW_NAME, argv[0]); ++ fprintf(stderr, ++ "Launch a command in a restricted environment.\n\n"); + fprintf(stderr, "Environment variables containing paths, " + "each separated by a colon:\n"); +- fprintf(stderr, "* %s: list of paths allowed to be used in a read-only way.\n", +- ENV_FS_RO_NAME); +- fprintf(stderr, "* %s: list of paths allowed to be used in a read-write way.\n", +- ENV_FS_RW_NAME); +- fprintf(stderr, "\nexample:\n" +- "%s=\"/bin:/lib:/usr:/proc:/etc:/dev/urandom\" " +- "%s=\"/dev/null:/dev/full:/dev/zero:/dev/pts:/tmp\" " +- "%s bash -i\n", +- ENV_FS_RO_NAME, ENV_FS_RW_NAME, argv[0]); ++ fprintf(stderr, ++ "* %s: list of paths allowed to be used in a read-only way.\n", ++ ENV_FS_RO_NAME); ++ fprintf(stderr, ++ "* %s: list of paths allowed to be used in a read-write way.\n", ++ ENV_FS_RW_NAME); ++ fprintf(stderr, ++ "\nexample:\n" ++ "%s=\"/bin:/lib:/usr:/proc:/etc:/dev/urandom\" " ++ "%s=\"/dev/null:/dev/full:/dev/zero:/dev/pts:/tmp\" " ++ "%s bash -i\n", ++ ENV_FS_RO_NAME, ENV_FS_RW_NAME, argv[0]); + return 1; + } + +- ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); ++ ruleset_fd = ++ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + if (ruleset_fd < 0) { + const int err = errno; + + perror("Failed to create a ruleset"); + switch (err) { + case ENOSYS: +- fprintf(stderr, "Hint: Landlock is not supported by the current kernel. " +- "To support it, build the kernel with " +- "CONFIG_SECURITY_LANDLOCK=y and prepend " +- "\"landlock,\" to the content of CONFIG_LSM.\n"); ++ fprintf(stderr, ++ "Hint: Landlock is not supported by the current kernel. " ++ "To support it, build the kernel with " ++ "CONFIG_SECURITY_LANDLOCK=y and prepend " ++ "\"landlock,\" to the content of CONFIG_LSM.\n"); + break; + case EOPNOTSUPP: +- fprintf(stderr, "Hint: Landlock is currently disabled. " +- "It can be enabled in the kernel configuration by " +- "prepending \"landlock,\" to the content of CONFIG_LSM, " +- "or at boot time by setting the same content to the " +- "\"lsm\" kernel parameter.\n"); ++ fprintf(stderr, ++ "Hint: Landlock is currently disabled. " ++ "It can be enabled in the kernel configuration by " ++ "prepending \"landlock,\" to the content of CONFIG_LSM, " ++ "or at boot time by setting the same content to the " ++ "\"lsm\" kernel parameter.\n"); + break; + } + return 1; + } + if (populate_ruleset(ENV_FS_RO_NAME, ruleset_fd, +- ACCESS_FS_ROUGHLY_READ)) { ++ ACCESS_FS_ROUGHLY_READ)) { + goto err_close_ruleset; + } + if (populate_ruleset(ENV_FS_RW_NAME, ruleset_fd, +- ACCESS_FS_ROUGHLY_READ | ACCESS_FS_ROUGHLY_WRITE)) { ++ ACCESS_FS_ROUGHLY_READ | ++ ACCESS_FS_ROUGHLY_WRITE)) { + goto err_close_ruleset; + } + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { +@@ -236,7 +244,7 @@ int main(const int argc, char *const arg + cmd_argv = argv + 1; + execvpe(cmd_path, cmd_argv, envp); + fprintf(stderr, "Failed to execute \"%s\": %s\n", cmd_path, +- strerror(errno)); ++ strerror(errno)); + fprintf(stderr, "Hint: access to the binary, the interpreter or " + "shared libraries may be denied.\n"); + return 1; diff --git a/queue-5.18/selftests-landlock-add-clang-format-exceptions.patch b/queue-5.18/selftests-landlock-add-clang-format-exceptions.patch new file mode 100644 index 00000000000..96f5d6e57c7 --- /dev/null +++ b/queue-5.18/selftests-landlock-add-clang-format-exceptions.patch @@ -0,0 +1,216 @@ +From 4598d9abf4215e1e371a35683350d50122793c80 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:05:09 +0200 +Subject: selftests/landlock: Add clang-format exceptions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 4598d9abf4215e1e371a35683350d50122793c80 upstream. + +In preparation to a following commit, add clang-format on and +clang-format off stanzas around constant definitions and the TEST_F_FORK +macro. This enables to keep aligned values, which is much more readable +than packed definitions. + +Add other clang-format exceptions for FIXTURE() and +FIXTURE_VARIANT_ADD() declarations to force space before open brace, +which is reported by checkpatch.pl . + +Link: https://lore.kernel.org/r/20220506160513.523257-4-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/landlock/common.h | 2 ++ + tools/testing/selftests/landlock/fs_test.c | 23 +++++++++++++++++------ + tools/testing/selftests/landlock/ptrace_test.c | 20 +++++++++++++++++++- + 3 files changed, 38 insertions(+), 7 deletions(-) + +--- a/tools/testing/selftests/landlock/common.h ++++ b/tools/testing/selftests/landlock/common.h +@@ -25,6 +25,7 @@ + * this to be possible, we must not call abort() but instead exit smoothly + * (hence the step print). + */ ++/* clang-format off */ + #define TEST_F_FORK(fixture_name, test_name) \ + static void fixture_name##_##test_name##_child( \ + struct __test_metadata *_metadata, \ +@@ -71,6 +72,7 @@ + FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \ + const FIXTURE_VARIANT(fixture_name) \ + __attribute__((unused)) *variant) ++/* clang-format on */ + + #ifndef landlock_create_ruleset + static inline int landlock_create_ruleset( +--- a/tools/testing/selftests/landlock/fs_test.c ++++ b/tools/testing/selftests/landlock/fs_test.c +@@ -221,8 +221,9 @@ static void remove_layout1(struct __test + EXPECT_EQ(0, remove_path(dir_s3d2)); + } + +-FIXTURE(layout1) { +-}; ++/* clang-format off */ ++FIXTURE(layout1) {}; ++/* clang-format on */ + + FIXTURE_SETUP(layout1) + { +@@ -376,6 +377,8 @@ TEST_F_FORK(layout1, inval) + ASSERT_EQ(0, close(ruleset_fd)); + } + ++/* clang-format off */ ++ + #define ACCESS_FILE ( \ + LANDLOCK_ACCESS_FS_EXECUTE | \ + LANDLOCK_ACCESS_FS_WRITE_FILE | \ +@@ -396,6 +399,8 @@ TEST_F_FORK(layout1, inval) + LANDLOCK_ACCESS_FS_MAKE_BLOCK | \ + ACCESS_LAST) + ++/* clang-format on */ ++ + TEST_F_FORK(layout1, file_access_rights) + { + __u64 access; +@@ -452,6 +457,8 @@ struct rule { + __u64 access; + }; + ++/* clang-format off */ ++ + #define ACCESS_RO ( \ + LANDLOCK_ACCESS_FS_READ_FILE | \ + LANDLOCK_ACCESS_FS_READ_DIR) +@@ -460,6 +467,8 @@ struct rule { + ACCESS_RO | \ + LANDLOCK_ACCESS_FS_WRITE_FILE) + ++/* clang-format on */ ++ + static int create_ruleset(struct __test_metadata *const _metadata, + const __u64 handled_access_fs, const struct rule rules[]) + { +@@ -2070,8 +2079,9 @@ TEST_F_FORK(layout1, proc_pipe) + ASSERT_EQ(0, close(pipe_fds[1])); + } + +-FIXTURE(layout1_bind) { +-}; ++/* clang-format off */ ++FIXTURE(layout1_bind) {}; ++/* clang-format on */ + + FIXTURE_SETUP(layout1_bind) + { +@@ -2411,8 +2421,9 @@ static const char (*merge_sub_files[])[] + * └── work + */ + +-FIXTURE(layout2_overlay) { +-}; ++/* clang-format off */ ++FIXTURE(layout2_overlay) {}; ++/* clang-format on */ + + FIXTURE_SETUP(layout2_overlay) + { +--- a/tools/testing/selftests/landlock/ptrace_test.c ++++ b/tools/testing/selftests/landlock/ptrace_test.c +@@ -59,7 +59,9 @@ static int test_ptrace_read(const pid_t + return 0; + } + +-FIXTURE(hierarchy) { }; ++/* clang-format off */ ++FIXTURE(hierarchy) {}; ++/* clang-format on */ + + FIXTURE_VARIANT(hierarchy) { + const bool domain_both; +@@ -83,7 +85,9 @@ FIXTURE_VARIANT(hierarchy) { + * \ P2 -> P1 : allow + * 'P2 + */ ++/* clang-format off */ + FIXTURE_VARIANT_ADD(hierarchy, allow_without_domain) { ++ /* clang-format on */ + .domain_both = false, + .domain_parent = false, + .domain_child = false, +@@ -98,7 +102,9 @@ FIXTURE_VARIANT_ADD(hierarchy, allow_wit + * | P2 | + * '------' + */ ++/* clang-format off */ + FIXTURE_VARIANT_ADD(hierarchy, allow_with_one_domain) { ++ /* clang-format on */ + .domain_both = false, + .domain_parent = false, + .domain_child = true, +@@ -112,7 +118,9 @@ FIXTURE_VARIANT_ADD(hierarchy, allow_wit + * ' + * P2 + */ ++/* clang-format off */ + FIXTURE_VARIANT_ADD(hierarchy, deny_with_parent_domain) { ++ /* clang-format on */ + .domain_both = false, + .domain_parent = true, + .domain_child = false, +@@ -127,7 +135,9 @@ FIXTURE_VARIANT_ADD(hierarchy, deny_with + * | P2 | + * '------' + */ ++/* clang-format off */ + FIXTURE_VARIANT_ADD(hierarchy, deny_with_sibling_domain) { ++ /* clang-format on */ + .domain_both = false, + .domain_parent = true, + .domain_child = true, +@@ -142,7 +152,9 @@ FIXTURE_VARIANT_ADD(hierarchy, deny_with + * | P2 | + * '-------------' + */ ++/* clang-format off */ + FIXTURE_VARIANT_ADD(hierarchy, allow_sibling_domain) { ++ /* clang-format on */ + .domain_both = true, + .domain_parent = false, + .domain_child = false, +@@ -158,7 +170,9 @@ FIXTURE_VARIANT_ADD(hierarchy, allow_sib + * | '------' | + * '-----------------' + */ ++/* clang-format off */ + FIXTURE_VARIANT_ADD(hierarchy, allow_with_nested_domain) { ++ /* clang-format on */ + .domain_both = true, + .domain_parent = false, + .domain_child = true, +@@ -174,7 +188,9 @@ FIXTURE_VARIANT_ADD(hierarchy, allow_wit + * | P2 | + * '-----------------' + */ ++/* clang-format off */ + FIXTURE_VARIANT_ADD(hierarchy, deny_with_nested_and_parent_domain) { ++ /* clang-format on */ + .domain_both = true, + .domain_parent = true, + .domain_child = false, +@@ -192,7 +208,9 @@ FIXTURE_VARIANT_ADD(hierarchy, deny_with + * | '------' | + * '-----------------' + */ ++/* clang-format off */ + FIXTURE_VARIANT_ADD(hierarchy, deny_with_forked_domain) { ++ /* clang-format on */ + .domain_both = true, + .domain_parent = true, + .domain_child = true, diff --git a/queue-5.18/selftests-landlock-add-tests-for-o_path.patch b/queue-5.18/selftests-landlock-add-tests-for-o_path.patch new file mode 100644 index 00000000000..b6fc6fc9805 --- /dev/null +++ b/queue-5.18/selftests-landlock-add-tests-for-o_path.patch @@ -0,0 +1,52 @@ +From d1788ad990874734341b05ab8ccb6448c09c6422 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:08:17 +0200 +Subject: selftests/landlock: Add tests for O_PATH +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit d1788ad990874734341b05ab8ccb6448c09c6422 upstream. + +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 +Link: https://lore.kernel.org/r/20220506160820.524344-8-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/landlock/fs_test.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- 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. */ diff --git a/queue-5.18/selftests-landlock-add-tests-for-unknown-access-rights.patch b/queue-5.18/selftests-landlock-add-tests-for-unknown-access-rights.patch new file mode 100644 index 00000000000..da4424359a0 --- /dev/null +++ b/queue-5.18/selftests-landlock-add-tests-for-unknown-access-rights.patch @@ -0,0 +1,48 @@ +From c56b3bf566da5a0dd3b58ad97a614b0928b06ebf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:08:14 +0200 +Subject: selftests/landlock: Add tests for unknown access rights +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit c56b3bf566da5a0dd3b58ad97a614b0928b06ebf upstream. + +Make sure that trying to use unknown access rights returns an error. + +Cc: Shuah Khan +Link: https://lore.kernel.org/r/20220506160820.524344-5-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/landlock/fs_test.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- 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) diff --git a/queue-5.18/selftests-landlock-extend-access-right-tests-to-directories.patch b/queue-5.18/selftests-landlock-extend-access-right-tests-to-directories.patch new file mode 100644 index 00000000000..54a1cb88034 --- /dev/null +++ b/queue-5.18/selftests-landlock-extend-access-right-tests-to-directories.patch @@ -0,0 +1,83 @@ +From d18955d094d09a220cf8f533f5e896a2fe31575a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:08:15 +0200 +Subject: selftests/landlock: Extend access right tests to directories +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit d18955d094d09a220cf8f533f5e896a2fe31575a upstream. + +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 +Link: https://lore.kernel.org/r/20220506160820.524344-6-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/landlock/fs_test.c | 30 +++++++++++++++++++++-------- + 1 file changed, 22 insertions(+), 8 deletions(-) + +--- 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) diff --git a/queue-5.18/selftests-landlock-extend-tests-for-minimal-valid-attribute-size.patch b/queue-5.18/selftests-landlock-extend-tests-for-minimal-valid-attribute-size.patch new file mode 100644 index 00000000000..5d78c5fc777 --- /dev/null +++ b/queue-5.18/selftests-landlock-extend-tests-for-minimal-valid-attribute-size.patch @@ -0,0 +1,45 @@ +From 291865bd7e8bb4b4033d341fa02dafa728e6378c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:08:13 +0200 +Subject: selftests/landlock: Extend tests for minimal valid attribute size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 291865bd7e8bb4b4033d341fa02dafa728e6378c upstream. + +This might be useful when the struct landlock_ruleset_attr will get more +fields. + +Cc: Shuah Khan +Link: https://lore.kernel.org/r/20220506160820.524344-4-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/landlock/base_test.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- 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)); diff --git a/queue-5.18/selftests-landlock-format-with-clang-format.patch b/queue-5.18/selftests-landlock-format-with-clang-format.patch new file mode 100644 index 00000000000..ccba58575fa --- /dev/null +++ b/queue-5.18/selftests-landlock-format-with-clang-format.patch @@ -0,0 +1,1513 @@ +From 371183fa578a4cf56b3ae12e54b7f01a4249add1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:05:11 +0200 +Subject: selftests/landlock: Format with clang-format +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 371183fa578a4cf56b3ae12e54b7f01a4249add1 upstream. + +Let's follow a consistent and documented coding style. Everything may +not be to our liking but it is better than tacit knowledge. Moreover, +this will help maintain style consistency between different developers. + +This contains only whitespace changes. + +Automatically formatted with: +clang-format-14 -i tools/testing/selftests/landlock/*.[ch] + +Link: https://lore.kernel.org/r/20220506160513.523257-6-mic@digikod.net +Cc: stable@vger.kernel.org +[mic: Update style according to +https://lore.kernel.org/r/02494cb8-2aa5-1769-f28d-d7206f284e5a@digikod.net] +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/landlock/base_test.c | 80 ++--- + tools/testing/selftests/landlock/common.h | 64 ++-- + tools/testing/selftests/landlock/fs_test.c | 399 +++++++++++++------------ + tools/testing/selftests/landlock/ptrace_test.c | 20 - + 4 files changed, 312 insertions(+), 251 deletions(-) + +--- a/tools/testing/selftests/landlock/base_test.c ++++ b/tools/testing/selftests/landlock/base_test.c +@@ -18,10 +18,11 @@ + #include "common.h" + + #ifndef O_PATH +-#define O_PATH 010000000 ++#define O_PATH 010000000 + #endif + +-TEST(inconsistent_attr) { ++TEST(inconsistent_attr) ++{ + const long page_size = sysconf(_SC_PAGESIZE); + char *const buf = malloc(page_size + 1); + struct landlock_ruleset_attr *const ruleset_attr = (void *)buf; +@@ -39,15 +40,16 @@ TEST(inconsistent_attr) { + /* The size if less than sizeof(struct landlock_attr_enforce). */ + ASSERT_EQ(EFAULT, errno); + +- ASSERT_EQ(-1, landlock_create_ruleset(NULL, +- sizeof(struct landlock_ruleset_attr), 0)); ++ ASSERT_EQ(-1, landlock_create_ruleset( ++ NULL, sizeof(struct landlock_ruleset_attr), 0)); + ASSERT_EQ(EFAULT, errno); + + ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, page_size + 1, 0)); + ASSERT_EQ(E2BIG, errno); + +- ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, +- sizeof(struct landlock_ruleset_attr), 0)); ++ ASSERT_EQ(-1, landlock_create_ruleset( ++ ruleset_attr, ++ sizeof(struct landlock_ruleset_attr), 0)); + ASSERT_EQ(ENOMSG, errno); + ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, page_size, 0)); + ASSERT_EQ(ENOMSG, errno); +@@ -63,32 +65,35 @@ TEST(inconsistent_attr) { + free(buf); + } + +-TEST(abi_version) { ++TEST(abi_version) ++{ + const struct landlock_ruleset_attr ruleset_attr = { + .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE, + }; + ASSERT_EQ(1, landlock_create_ruleset(NULL, 0, +- LANDLOCK_CREATE_RULESET_VERSION)); ++ LANDLOCK_CREATE_RULESET_VERSION)); + + ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, +- LANDLOCK_CREATE_RULESET_VERSION)); ++ LANDLOCK_CREATE_RULESET_VERSION)); + ASSERT_EQ(EINVAL, errno); + + ASSERT_EQ(-1, landlock_create_ruleset(NULL, sizeof(ruleset_attr), +- LANDLOCK_CREATE_RULESET_VERSION)); ++ LANDLOCK_CREATE_RULESET_VERSION)); + ASSERT_EQ(EINVAL, errno); + +- ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, +- sizeof(ruleset_attr), +- LANDLOCK_CREATE_RULESET_VERSION)); ++ ASSERT_EQ(-1, ++ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), ++ LANDLOCK_CREATE_RULESET_VERSION)); + ASSERT_EQ(EINVAL, errno); + + ASSERT_EQ(-1, landlock_create_ruleset(NULL, 0, +- LANDLOCK_CREATE_RULESET_VERSION | 1 << 31)); ++ LANDLOCK_CREATE_RULESET_VERSION | ++ 1 << 31)); + ASSERT_EQ(EINVAL, errno); + } + +-TEST(inval_create_ruleset_flags) { ++TEST(inval_create_ruleset_flags) ++{ + const int last_flag = LANDLOCK_CREATE_RULESET_VERSION; + const int invalid_flag = last_flag << 1; + const struct landlock_ruleset_attr ruleset_attr = { +@@ -102,38 +107,42 @@ TEST(inval_create_ruleset_flags) { + ASSERT_EQ(EINVAL, errno); + + ASSERT_EQ(-1, landlock_create_ruleset(NULL, sizeof(ruleset_attr), +- invalid_flag)); ++ invalid_flag)); + ASSERT_EQ(EINVAL, errno); + +- ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, +- sizeof(ruleset_attr), invalid_flag)); ++ ASSERT_EQ(-1, ++ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), ++ invalid_flag)); + ASSERT_EQ(EINVAL, errno); + } + +-TEST(empty_path_beneath_attr) { ++TEST(empty_path_beneath_attr) ++{ + const struct landlock_ruleset_attr ruleset_attr = { + .handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE, + }; +- const int ruleset_fd = landlock_create_ruleset(&ruleset_attr, +- sizeof(ruleset_attr), 0); ++ 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 */ + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, +- NULL, 0)); ++ NULL, 0)); + ASSERT_EQ(EFAULT, errno); + ASSERT_EQ(0, close(ruleset_fd)); + } + +-TEST(inval_fd_enforce) { ++TEST(inval_fd_enforce) ++{ + ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); + + ASSERT_EQ(-1, landlock_restrict_self(-1, 0)); + ASSERT_EQ(EBADF, errno); + } + +-TEST(unpriv_enforce_without_no_new_privs) { ++TEST(unpriv_enforce_without_no_new_privs) ++{ + int err; + + drop_caps(_metadata); +@@ -151,8 +160,8 @@ TEST(ruleset_fd_io) + char buf; + + drop_caps(_metadata); +- ruleset_fd = landlock_create_ruleset(&ruleset_attr, +- sizeof(ruleset_attr), 0); ++ ruleset_fd = ++ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + ASSERT_LE(0, ruleset_fd); + + ASSERT_EQ(-1, write(ruleset_fd, ".", 1)); +@@ -197,14 +206,15 @@ TEST(ruleset_fd_transfer) + drop_caps(_metadata); + + /* Creates a test ruleset with a simple rule. */ +- ruleset_fd_tx = landlock_create_ruleset(&ruleset_attr, +- sizeof(ruleset_attr), 0); ++ ruleset_fd_tx = ++ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + ASSERT_LE(0, ruleset_fd_tx); +- path_beneath_attr.parent_fd = open("/tmp", O_PATH | O_NOFOLLOW | +- O_DIRECTORY | O_CLOEXEC); ++ 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_tx, LANDLOCK_RULE_PATH_BENEATH, +- &path_beneath_attr, 0)); ++ ASSERT_EQ(0, ++ landlock_add_rule(ruleset_fd_tx, LANDLOCK_RULE_PATH_BENEATH, ++ &path_beneath_attr, 0)); + ASSERT_EQ(0, close(path_beneath_attr.parent_fd)); + + cmsg = CMSG_FIRSTHDR(&msg); +@@ -215,7 +225,8 @@ TEST(ruleset_fd_transfer) + memcpy(CMSG_DATA(cmsg), &ruleset_fd_tx, sizeof(ruleset_fd_tx)); + + /* Sends the ruleset FD over a socketpair and then close it. */ +- ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, socket_fds)); ++ ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, ++ socket_fds)); + ASSERT_EQ(sizeof(data_tx), sendmsg(socket_fds[0], &msg, 0)); + ASSERT_EQ(0, close(socket_fds[0])); + ASSERT_EQ(0, close(ruleset_fd_tx)); +@@ -226,7 +237,8 @@ TEST(ruleset_fd_transfer) + int ruleset_fd_rx; + + *(char *)msg.msg_iov->iov_base = '\0'; +- ASSERT_EQ(sizeof(data_tx), recvmsg(socket_fds[1], &msg, MSG_CMSG_CLOEXEC)); ++ ASSERT_EQ(sizeof(data_tx), ++ recvmsg(socket_fds[1], &msg, MSG_CMSG_CLOEXEC)); + ASSERT_EQ('.', *(char *)msg.msg_iov->iov_base); + ASSERT_EQ(0, close(socket_fds[1])); + cmsg = CMSG_FIRSTHDR(&msg); +--- a/tools/testing/selftests/landlock/common.h ++++ b/tools/testing/selftests/landlock/common.h +@@ -75,9 +75,9 @@ + /* clang-format on */ + + #ifndef landlock_create_ruleset +-static inline int landlock_create_ruleset( +- const struct landlock_ruleset_attr *const attr, +- const size_t size, const __u32 flags) ++static inline int ++landlock_create_ruleset(const struct landlock_ruleset_attr *const attr, ++ const size_t size, const __u32 flags) + { + return syscall(__NR_landlock_create_ruleset, attr, size, flags); + } +@@ -85,17 +85,18 @@ static inline int landlock_create_rulese + + #ifndef landlock_add_rule + static inline int landlock_add_rule(const int ruleset_fd, +- const enum landlock_rule_type rule_type, +- const void *const rule_attr, const __u32 flags) ++ const enum landlock_rule_type rule_type, ++ const void *const rule_attr, ++ const __u32 flags) + { +- return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, +- rule_attr, flags); ++ return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, rule_attr, ++ flags); + } + #endif + + #ifndef landlock_restrict_self + static inline int landlock_restrict_self(const int ruleset_fd, +- const __u32 flags) ++ const __u32 flags) + { + return syscall(__NR_landlock_restrict_self, ruleset_fd, flags); + } +@@ -113,69 +114,76 @@ static void _init_caps(struct __test_met + }; + + cap_p = cap_get_proc(); +- EXPECT_NE(NULL, cap_p) { ++ EXPECT_NE(NULL, cap_p) ++ { + TH_LOG("Failed to cap_get_proc: %s", strerror(errno)); + } +- EXPECT_NE(-1, cap_clear(cap_p)) { ++ EXPECT_NE(-1, cap_clear(cap_p)) ++ { + TH_LOG("Failed to cap_clear: %s", strerror(errno)); + } + if (!drop_all) { + EXPECT_NE(-1, cap_set_flag(cap_p, CAP_PERMITTED, +- ARRAY_SIZE(caps), caps, CAP_SET)) { ++ ARRAY_SIZE(caps), caps, CAP_SET)) ++ { + TH_LOG("Failed to cap_set_flag: %s", strerror(errno)); + } + } +- EXPECT_NE(-1, cap_set_proc(cap_p)) { ++ EXPECT_NE(-1, cap_set_proc(cap_p)) ++ { + TH_LOG("Failed to cap_set_proc: %s", strerror(errno)); + } +- EXPECT_NE(-1, cap_free(cap_p)) { ++ EXPECT_NE(-1, cap_free(cap_p)) ++ { + TH_LOG("Failed to cap_free: %s", strerror(errno)); + } + } + + /* We cannot put such helpers in a library because of kselftest_harness.h . */ +-__attribute__((__unused__)) +-static void disable_caps(struct __test_metadata *const _metadata) ++__attribute__((__unused__)) static void ++disable_caps(struct __test_metadata *const _metadata) + { + _init_caps(_metadata, false); + } + +-__attribute__((__unused__)) +-static void drop_caps(struct __test_metadata *const _metadata) ++__attribute__((__unused__)) static void ++drop_caps(struct __test_metadata *const _metadata) + { + _init_caps(_metadata, true); + } + + static void _effective_cap(struct __test_metadata *const _metadata, +- const cap_value_t caps, const cap_flag_value_t value) ++ const cap_value_t caps, const cap_flag_value_t value) + { + cap_t cap_p; + + cap_p = cap_get_proc(); +- EXPECT_NE(NULL, cap_p) { ++ EXPECT_NE(NULL, cap_p) ++ { + TH_LOG("Failed to cap_get_proc: %s", strerror(errno)); + } +- EXPECT_NE(-1, cap_set_flag(cap_p, CAP_EFFECTIVE, 1, &caps, value)) { ++ EXPECT_NE(-1, cap_set_flag(cap_p, CAP_EFFECTIVE, 1, &caps, value)) ++ { + TH_LOG("Failed to cap_set_flag: %s", strerror(errno)); + } +- EXPECT_NE(-1, cap_set_proc(cap_p)) { ++ EXPECT_NE(-1, cap_set_proc(cap_p)) ++ { + TH_LOG("Failed to cap_set_proc: %s", strerror(errno)); + } +- EXPECT_NE(-1, cap_free(cap_p)) { ++ EXPECT_NE(-1, cap_free(cap_p)) ++ { + TH_LOG("Failed to cap_free: %s", strerror(errno)); + } + } + +-__attribute__((__unused__)) +-static void set_cap(struct __test_metadata *const _metadata, +- const cap_value_t caps) ++__attribute__((__unused__)) static void ++set_cap(struct __test_metadata *const _metadata, const cap_value_t caps) + { + _effective_cap(_metadata, caps, CAP_SET); + } + +-__attribute__((__unused__)) +-static void clear_cap(struct __test_metadata *const _metadata, +- const cap_value_t caps) ++__attribute__((__unused__)) static void ++clear_cap(struct __test_metadata *const _metadata, const cap_value_t caps) + { + _effective_cap(_metadata, caps, CAP_CLEAR); + } +--- a/tools/testing/selftests/landlock/fs_test.c ++++ b/tools/testing/selftests/landlock/fs_test.c +@@ -22,8 +22,8 @@ + + #include "common.h" + +-#define TMP_DIR "tmp" +-#define BINARY_PATH "./true" ++#define TMP_DIR "tmp" ++#define BINARY_PATH "./true" + + /* Paths (sibling number and depth) */ + static const char dir_s1d1[] = TMP_DIR "/s1d1"; +@@ -75,7 +75,7 @@ static const char dir_s3d3[] = TMP_DIR " + */ + + static void mkdir_parents(struct __test_metadata *const _metadata, +- const char *const path) ++ const char *const path) + { + char *walker; + const char *parent; +@@ -90,9 +90,10 @@ static void mkdir_parents(struct __test_ + continue; + walker[i] = '\0'; + err = mkdir(parent, 0700); +- ASSERT_FALSE(err && errno != EEXIST) { +- TH_LOG("Failed to create directory \"%s\": %s", +- parent, strerror(errno)); ++ ASSERT_FALSE(err && errno != EEXIST) ++ { ++ TH_LOG("Failed to create directory \"%s\": %s", parent, ++ strerror(errno)); + } + walker[i] = '/'; + } +@@ -100,22 +101,24 @@ static void mkdir_parents(struct __test_ + } + + static void create_directory(struct __test_metadata *const _metadata, +- const char *const path) ++ const char *const path) + { + mkdir_parents(_metadata, path); +- ASSERT_EQ(0, mkdir(path, 0700)) { ++ ASSERT_EQ(0, mkdir(path, 0700)) ++ { + TH_LOG("Failed to create directory \"%s\": %s", path, +- strerror(errno)); ++ strerror(errno)); + } + } + + static void create_file(struct __test_metadata *const _metadata, +- const char *const path) ++ const char *const path) + { + mkdir_parents(_metadata, path); +- ASSERT_EQ(0, mknod(path, S_IFREG | 0700, 0)) { ++ ASSERT_EQ(0, mknod(path, S_IFREG | 0700, 0)) ++ { + TH_LOG("Failed to create file \"%s\": %s", path, +- strerror(errno)); ++ strerror(errno)); + } + } + +@@ -243,7 +246,8 @@ FIXTURE_TEARDOWN(layout1) + * This helper enables to use the ASSERT_* macros and print the line number + * pointing to the test caller. + */ +-static int test_open_rel(const int dirfd, const char *const path, const int flags) ++static int test_open_rel(const int dirfd, const char *const path, ++ const int flags) + { + int fd; + +@@ -292,23 +296,23 @@ TEST_F_FORK(layout1, inval) + { + struct landlock_path_beneath_attr path_beneath = { + .allowed_access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, ++ LANDLOCK_ACCESS_FS_WRITE_FILE, + .parent_fd = -1, + }; + struct landlock_ruleset_attr ruleset_attr = { + .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, ++ LANDLOCK_ACCESS_FS_WRITE_FILE, + }; + int ruleset_fd; + +- path_beneath.parent_fd = open(dir_s1d2, O_PATH | O_DIRECTORY | +- O_CLOEXEC); ++ path_beneath.parent_fd = ++ open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC); + ASSERT_LE(0, path_beneath.parent_fd); + + ruleset_fd = open(dir_s1d1, O_PATH | O_DIRECTORY | O_CLOEXEC); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, +- &path_beneath, 0)); ++ &path_beneath, 0)); + /* Returns EBADF because ruleset_fd is not a landlock-ruleset FD. */ + ASSERT_EQ(EBADF, errno); + ASSERT_EQ(0, close(ruleset_fd)); +@@ -316,55 +320,55 @@ TEST_F_FORK(layout1, inval) + ruleset_fd = open(dir_s1d1, O_DIRECTORY | O_CLOEXEC); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, +- &path_beneath, 0)); ++ &path_beneath, 0)); + /* Returns EBADFD because ruleset_fd is not a valid ruleset. */ + ASSERT_EQ(EBADFD, errno); + ASSERT_EQ(0, close(ruleset_fd)); + + /* Gets a real ruleset. */ +- ruleset_fd = landlock_create_ruleset(&ruleset_attr, +- sizeof(ruleset_attr), 0); ++ ruleset_fd = ++ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, +- &path_beneath, 0)); ++ &path_beneath, 0)); + ASSERT_EQ(0, close(path_beneath.parent_fd)); + + /* Tests without O_PATH. */ + path_beneath.parent_fd = open(dir_s1d2, O_DIRECTORY | O_CLOEXEC); + ASSERT_LE(0, path_beneath.parent_fd); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, +- &path_beneath, 0)); ++ &path_beneath, 0)); + ASSERT_EQ(0, close(path_beneath.parent_fd)); + + /* Tests with a ruleset FD. */ + path_beneath.parent_fd = ruleset_fd; + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, +- &path_beneath, 0)); ++ &path_beneath, 0)); + ASSERT_EQ(EBADFD, errno); + + /* Checks unhandled allowed_access. */ +- path_beneath.parent_fd = open(dir_s1d2, O_PATH | O_DIRECTORY | +- O_CLOEXEC); ++ path_beneath.parent_fd = ++ open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC); + ASSERT_LE(0, path_beneath.parent_fd); + + /* Test with legitimate values. */ + path_beneath.allowed_access |= LANDLOCK_ACCESS_FS_EXECUTE; + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, +- &path_beneath, 0)); ++ &path_beneath, 0)); + ASSERT_EQ(EINVAL, errno); + path_beneath.allowed_access &= ~LANDLOCK_ACCESS_FS_EXECUTE; + + /* Test with unknown (64-bits) value. */ + path_beneath.allowed_access |= (1ULL << 60); + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, +- &path_beneath, 0)); ++ &path_beneath, 0)); + ASSERT_EQ(EINVAL, errno); + path_beneath.allowed_access &= ~(1ULL << 60); + + /* Test with no access. */ + path_beneath.allowed_access = 0; + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, +- &path_beneath, 0)); ++ &path_beneath, 0)); + ASSERT_EQ(ENOMSG, errno); + path_beneath.allowed_access &= ~(1ULL << 60); + +@@ -409,8 +413,8 @@ TEST_F_FORK(layout1, file_access_rights) + struct landlock_ruleset_attr ruleset_attr = { + .handled_access_fs = ACCESS_ALL, + }; +- const int ruleset_fd = landlock_create_ruleset(&ruleset_attr, +- sizeof(ruleset_attr), 0); ++ const int ruleset_fd = ++ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + + ASSERT_LE(0, ruleset_fd); + +@@ -420,7 +424,7 @@ TEST_F_FORK(layout1, file_access_rights) + for (access = 1; access <= ACCESS_LAST; access <<= 1) { + path_beneath.allowed_access = access; + err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, +- &path_beneath, 0); ++ &path_beneath, 0); + if ((access | ACCESS_FILE) == ACCESS_FILE) { + ASSERT_EQ(0, err); + } else { +@@ -432,22 +436,24 @@ TEST_F_FORK(layout1, file_access_rights) + } + + static void add_path_beneath(struct __test_metadata *const _metadata, +- const int ruleset_fd, const __u64 allowed_access, +- const char *const path) ++ const int ruleset_fd, const __u64 allowed_access, ++ const char *const path) + { + struct landlock_path_beneath_attr path_beneath = { + .allowed_access = allowed_access, + }; + + path_beneath.parent_fd = open(path, O_PATH | O_CLOEXEC); +- ASSERT_LE(0, path_beneath.parent_fd) { ++ ASSERT_LE(0, path_beneath.parent_fd) ++ { + TH_LOG("Failed to open directory \"%s\": %s", path, +- strerror(errno)); ++ strerror(errno)); + } + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, +- &path_beneath, 0)) { ++ &path_beneath, 0)) ++ { + TH_LOG("Failed to update the ruleset with \"%s\": %s", path, +- strerror(errno)); ++ strerror(errno)); + } + ASSERT_EQ(0, close(path_beneath.parent_fd)); + } +@@ -470,38 +476,43 @@ struct rule { + /* clang-format on */ + + static int create_ruleset(struct __test_metadata *const _metadata, +- const __u64 handled_access_fs, const struct rule rules[]) ++ const __u64 handled_access_fs, ++ const struct rule rules[]) + { + int ruleset_fd, i; + struct landlock_ruleset_attr ruleset_attr = { + .handled_access_fs = handled_access_fs, + }; + +- ASSERT_NE(NULL, rules) { ++ ASSERT_NE(NULL, rules) ++ { + TH_LOG("No rule list"); + } +- ASSERT_NE(NULL, rules[0].path) { ++ ASSERT_NE(NULL, rules[0].path) ++ { + TH_LOG("Empty rule list"); + } + +- ruleset_fd = landlock_create_ruleset(&ruleset_attr, +- sizeof(ruleset_attr), 0); +- ASSERT_LE(0, ruleset_fd) { ++ ruleset_fd = ++ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); ++ ASSERT_LE(0, ruleset_fd) ++ { + TH_LOG("Failed to create a ruleset: %s", strerror(errno)); + } + + for (i = 0; rules[i].path; i++) { + add_path_beneath(_metadata, ruleset_fd, rules[i].access, +- rules[i].path); ++ rules[i].path); + } + return ruleset_fd; + } + + static void enforce_ruleset(struct __test_metadata *const _metadata, +- const int ruleset_fd) ++ const int ruleset_fd) + { + ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); +- ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0)) { ++ ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0)) ++ { + TH_LOG("Failed to enforce ruleset: %s", strerror(errno)); + } + } +@@ -512,13 +523,14 @@ TEST_F_FORK(layout1, proc_nsfs) + { + .path = "/dev/null", + .access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, ++ LANDLOCK_ACCESS_FS_WRITE_FILE, + }, + {}, + }; + struct landlock_path_beneath_attr path_beneath; +- const int ruleset_fd = create_ruleset(_metadata, rules[0].access | +- LANDLOCK_ACCESS_FS_READ_DIR, rules); ++ const int ruleset_fd = create_ruleset( ++ _metadata, rules[0].access | LANDLOCK_ACCESS_FS_READ_DIR, ++ rules); + + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, test_open("/proc/self/ns/mnt", O_RDONLY)); +@@ -545,16 +557,17 @@ TEST_F_FORK(layout1, proc_nsfs) + * references to a ruleset. + */ + path_beneath.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, ++ LANDLOCK_ACCESS_FS_WRITE_FILE, + path_beneath.parent_fd = open("/proc/self/ns/mnt", O_PATH | O_CLOEXEC); + ASSERT_LE(0, path_beneath.parent_fd); + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, +- &path_beneath, 0)); ++ &path_beneath, 0)); + ASSERT_EQ(EBADFD, errno); + ASSERT_EQ(0, close(path_beneath.parent_fd)); + } + +-TEST_F_FORK(layout1, unpriv) { ++TEST_F_FORK(layout1, unpriv) ++{ + const struct rule rules[] = { + { + .path = dir_s1d2, +@@ -586,7 +599,7 @@ TEST_F_FORK(layout1, effective_access) + { + .path = file1_s2d2, + .access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, ++ LANDLOCK_ACCESS_FS_WRITE_FILE, + }, + {}, + }; +@@ -662,12 +675,12 @@ TEST_F_FORK(layout1, ruleset_overlap) + { + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, ++ LANDLOCK_ACCESS_FS_WRITE_FILE, + }, + { + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_READ_DIR, ++ LANDLOCK_ACCESS_FS_READ_DIR, + }, + {}, + }; +@@ -717,8 +730,8 @@ TEST_F_FORK(layout1, non_overlapping_acc + ASSERT_EQ(0, unlink(file1_s1d1)); + ASSERT_EQ(0, unlink(file1_s1d2)); + +- ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, +- layer1); ++ ruleset_fd = ++ create_ruleset(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, layer1); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); +@@ -729,7 +742,7 @@ TEST_F_FORK(layout1, non_overlapping_acc + ASSERT_EQ(0, unlink(file1_s1d2)); + + ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_REMOVE_FILE, +- layer2); ++ layer2); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); +@@ -775,7 +788,7 @@ TEST_F_FORK(layout1, interleaved_masked_ + { + .path = dir_s1d3, + .access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, ++ LANDLOCK_ACCESS_FS_WRITE_FILE, + }, + /* ...but also denies read access via its grandparent directory. */ + { +@@ -839,7 +852,7 @@ TEST_F_FORK(layout1, interleaved_masked_ + int ruleset_fd; + + ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE, +- layer1_read); ++ layer1_read); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); +@@ -849,8 +862,10 @@ TEST_F_FORK(layout1, interleaved_masked_ + ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY)); + ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY)); + +- ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, layer2_read_write); ++ ruleset_fd = create_ruleset(_metadata, ++ LANDLOCK_ACCESS_FS_READ_FILE | ++ LANDLOCK_ACCESS_FS_WRITE_FILE, ++ layer2_read_write); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); +@@ -861,7 +876,7 @@ TEST_F_FORK(layout1, interleaved_masked_ + ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY)); + + ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE, +- layer3_read); ++ layer3_read); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); +@@ -872,8 +887,10 @@ TEST_F_FORK(layout1, interleaved_masked_ + ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY)); + + /* This time, denies write access for the file hierarchy. */ +- ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, layer4_read_write); ++ ruleset_fd = create_ruleset(_metadata, ++ LANDLOCK_ACCESS_FS_READ_FILE | ++ LANDLOCK_ACCESS_FS_WRITE_FILE, ++ layer4_read_write); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); +@@ -888,7 +905,7 @@ TEST_F_FORK(layout1, interleaved_masked_ + ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY)); + + ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE, +- layer5_read); ++ layer5_read); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); +@@ -900,7 +917,7 @@ TEST_F_FORK(layout1, interleaved_masked_ + ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY)); + + ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_EXECUTE, +- layer6_execute); ++ layer6_execute); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); +@@ -911,8 +928,10 @@ TEST_F_FORK(layout1, interleaved_masked_ + ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY)); + ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY)); + +- ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, layer7_read_write); ++ ruleset_fd = create_ruleset(_metadata, ++ LANDLOCK_ACCESS_FS_READ_FILE | ++ LANDLOCK_ACCESS_FS_WRITE_FILE, ++ layer7_read_write); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); +@@ -930,7 +949,7 @@ TEST_F_FORK(layout1, inherit_subset) + { + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_READ_DIR, ++ LANDLOCK_ACCESS_FS_READ_DIR, + }, + {}, + }; +@@ -958,7 +977,7 @@ TEST_F_FORK(layout1, inherit_subset) + * ANDed with the previous ones. + */ + add_path_beneath(_metadata, ruleset_fd, LANDLOCK_ACCESS_FS_WRITE_FILE, +- dir_s1d2); ++ dir_s1d2); + /* + * According to ruleset_fd, dir_s1d2 should now have the + * LANDLOCK_ACCESS_FS_READ_FILE and LANDLOCK_ACCESS_FS_WRITE_FILE +@@ -1013,7 +1032,7 @@ TEST_F_FORK(layout1, inherit_subset) + * that there was no rule tied to it before. + */ + add_path_beneath(_metadata, ruleset_fd, LANDLOCK_ACCESS_FS_WRITE_FILE, +- dir_s1d3); ++ dir_s1d3); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + +@@ -1063,8 +1082,10 @@ TEST_F_FORK(layout1, inherit_superset) + ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY)); + + /* Now dir_s1d2, parent of dir_s1d3, gets a new rule tied to it. */ +- add_path_beneath(_metadata, ruleset_fd, LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_READ_DIR, dir_s1d2); ++ add_path_beneath(_metadata, ruleset_fd, ++ LANDLOCK_ACCESS_FS_READ_FILE | ++ LANDLOCK_ACCESS_FS_READ_DIR, ++ dir_s1d2); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + +@@ -1106,15 +1127,15 @@ TEST_F_FORK(layout1, empty_or_same_rules + int ruleset_fd; + + /* Tests empty handled_access_fs. */ +- ruleset_fd = landlock_create_ruleset(&ruleset_attr, +- sizeof(ruleset_attr), 0); ++ ruleset_fd = ++ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + ASSERT_LE(-1, ruleset_fd); + ASSERT_EQ(ENOMSG, errno); + + /* Enforces policy which deny read access to all files. */ + ruleset_attr.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE; +- ruleset_fd = landlock_create_ruleset(&ruleset_attr, +- sizeof(ruleset_attr), 0); ++ ruleset_fd = ++ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY)); +@@ -1122,8 +1143,8 @@ TEST_F_FORK(layout1, empty_or_same_rules + + /* Nests a policy which deny read access to all directories. */ + ruleset_attr.handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR; +- ruleset_fd = landlock_create_ruleset(&ruleset_attr, +- sizeof(ruleset_attr), 0); ++ ruleset_fd = ++ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY)); +@@ -1258,7 +1279,8 @@ TEST_F_FORK(layout1, rule_inside_mount_n + int ruleset_fd; + + set_cap(_metadata, CAP_SYS_ADMIN); +- ASSERT_EQ(0, syscall(SYS_pivot_root, dir_s3d2, dir_s3d3)) { ++ ASSERT_EQ(0, syscall(SYS_pivot_root, dir_s3d2, dir_s3d3)) ++ { + TH_LOG("Failed to pivot root: %s", strerror(errno)); + }; + ASSERT_EQ(0, chdir("/")); +@@ -1311,12 +1333,13 @@ TEST_F_FORK(layout1, move_mount) + + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, syscall(SYS_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD, +- dir_s1d2, 0)) { ++ 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, +- dir_s3d2, 0)); ++ dir_s3d2, 0)); + clear_cap(_metadata, CAP_SYS_ADMIN); + + enforce_ruleset(_metadata, ruleset_fd); +@@ -1324,7 +1347,7 @@ TEST_F_FORK(layout1, move_mount) + + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(-1, syscall(SYS_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD, +- dir_s1d2, 0)); ++ dir_s1d2, 0)); + ASSERT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + } +@@ -1371,7 +1394,7 @@ enum relative_access { + }; + + static void test_relative_path(struct __test_metadata *const _metadata, +- const enum relative_access rel) ++ const enum relative_access rel) + { + /* + * Common layer to check that chroot doesn't ignore it (i.e. a chroot +@@ -1434,14 +1457,16 @@ static void test_relative_path(struct __ + break; + case REL_CHROOT_ONLY: + /* Do chroot into dir_s1d2 (relative to dir_s2d2). */ +- ASSERT_EQ(0, chroot("../../s1d1/s1d2")) { ++ ASSERT_EQ(0, chroot("../../s1d1/s1d2")) ++ { + TH_LOG("Failed to chroot: %s", strerror(errno)); + } + dirfd = AT_FDCWD; + break; + case REL_CHROOT_CHDIR: + /* Do chroot into dir_s1d2. */ +- ASSERT_EQ(0, chroot(".")) { ++ ASSERT_EQ(0, chroot(".")) ++ { + TH_LOG("Failed to chroot: %s", strerror(errno)); + } + dirfd = AT_FDCWD; +@@ -1449,7 +1474,7 @@ static void test_relative_path(struct __ + } + + ASSERT_EQ((rel == REL_CHROOT_CHDIR) ? 0 : EACCES, +- test_open_rel(dirfd, "..", O_RDONLY)); ++ test_open_rel(dirfd, "..", O_RDONLY)); + ASSERT_EQ(0, test_open_rel(dirfd, ".", O_RDONLY)); + + if (rel == REL_CHROOT_ONLY) { +@@ -1471,11 +1496,13 @@ static void test_relative_path(struct __ + if (rel != REL_CHROOT_CHDIR) { + ASSERT_EQ(EACCES, test_open_rel(dirfd, "../../s1d1", O_RDONLY)); + ASSERT_EQ(0, test_open_rel(dirfd, "../../s1d1/s1d2", O_RDONLY)); +- ASSERT_EQ(0, test_open_rel(dirfd, "../../s1d1/s1d2/s1d3", O_RDONLY)); ++ ASSERT_EQ(0, test_open_rel(dirfd, "../../s1d1/s1d2/s1d3", ++ O_RDONLY)); + + ASSERT_EQ(EACCES, test_open_rel(dirfd, "../../s2d1", O_RDONLY)); + ASSERT_EQ(0, test_open_rel(dirfd, "../../s2d1/s2d2", O_RDONLY)); +- ASSERT_EQ(0, test_open_rel(dirfd, "../../s2d1/s2d2/s2d3", O_RDONLY)); ++ ASSERT_EQ(0, test_open_rel(dirfd, "../../s2d1/s2d2/s2d3", ++ O_RDONLY)); + } + + if (rel == REL_OPEN) +@@ -1504,40 +1531,42 @@ TEST_F_FORK(layout1, relative_chroot_chd + } + + static void copy_binary(struct __test_metadata *const _metadata, +- const char *const dst_path) ++ const char *const dst_path) + { + int dst_fd, src_fd; + struct stat statbuf; + + dst_fd = open(dst_path, O_WRONLY | O_TRUNC | O_CLOEXEC); +- ASSERT_LE(0, dst_fd) { +- TH_LOG("Failed to open \"%s\": %s", dst_path, +- strerror(errno)); ++ ASSERT_LE(0, dst_fd) ++ { ++ TH_LOG("Failed to open \"%s\": %s", dst_path, strerror(errno)); + } + src_fd = open(BINARY_PATH, O_RDONLY | O_CLOEXEC); +- ASSERT_LE(0, src_fd) { ++ ASSERT_LE(0, src_fd) ++ { + TH_LOG("Failed to open \"" BINARY_PATH "\": %s", +- strerror(errno)); ++ strerror(errno)); + } + ASSERT_EQ(0, fstat(src_fd, &statbuf)); +- ASSERT_EQ(statbuf.st_size, sendfile(dst_fd, src_fd, 0, +- statbuf.st_size)); ++ ASSERT_EQ(statbuf.st_size, ++ sendfile(dst_fd, src_fd, 0, statbuf.st_size)); + ASSERT_EQ(0, close(src_fd)); + ASSERT_EQ(0, close(dst_fd)); + } + +-static void test_execute(struct __test_metadata *const _metadata, +- const int err, const char *const path) ++static void test_execute(struct __test_metadata *const _metadata, const int err, ++ const char *const path) + { + int status; +- char *const argv[] = {(char *)path, NULL}; ++ char *const argv[] = { (char *)path, NULL }; + const pid_t child = fork(); + + ASSERT_LE(0, child); + if (child == 0) { +- ASSERT_EQ(err ? -1 : 0, execve(path, argv, NULL)) { ++ ASSERT_EQ(err ? -1 : 0, execve(path, argv, NULL)) ++ { + TH_LOG("Failed to execute \"%s\": %s", path, +- strerror(errno)); ++ strerror(errno)); + }; + ASSERT_EQ(err, errno); + _exit(_metadata->passed ? 2 : 1); +@@ -1545,9 +1574,10 @@ static void test_execute(struct __test_m + } + ASSERT_EQ(child, waitpid(child, &status, 0)); + ASSERT_EQ(1, WIFEXITED(status)); +- ASSERT_EQ(err ? 2 : 0, WEXITSTATUS(status)) { ++ ASSERT_EQ(err ? 2 : 0, WEXITSTATUS(status)) ++ { + TH_LOG("Unexpected return code for \"%s\": %s", path, +- strerror(errno)); ++ strerror(errno)); + }; + } + +@@ -1560,8 +1590,8 @@ TEST_F_FORK(layout1, execute) + }, + {}, + }; +- const int ruleset_fd = create_ruleset(_metadata, rules[0].access, +- rules); ++ const int ruleset_fd = ++ create_ruleset(_metadata, rules[0].access, rules); + + ASSERT_LE(0, ruleset_fd); + copy_binary(_metadata, file1_s1d1); +@@ -1593,8 +1623,8 @@ TEST_F_FORK(layout1, link) + }, + {}, + }; +- const int ruleset_fd = create_ruleset(_metadata, rules[0].access, +- rules); ++ const int ruleset_fd = ++ create_ruleset(_metadata, rules[0].access, rules); + + ASSERT_LE(0, ruleset_fd); + +@@ -1630,8 +1660,8 @@ TEST_F_FORK(layout1, rename_file) + }, + {}, + }; +- const int ruleset_fd = create_ruleset(_metadata, rules[0].access, +- rules); ++ const int ruleset_fd = ++ create_ruleset(_metadata, rules[0].access, rules); + + ASSERT_LE(0, ruleset_fd); + +@@ -1684,14 +1714,14 @@ TEST_F_FORK(layout1, rename_file) + + /* Exchanges and renames files with same parent. */ + ASSERT_EQ(0, renameat2(AT_FDCWD, file2_s2d3, AT_FDCWD, file1_s2d3, +- RENAME_EXCHANGE)); ++ RENAME_EXCHANGE)); + ASSERT_EQ(0, rename(file2_s2d3, file1_s2d3)); + + /* Exchanges files and directories with same parent, twice. */ + ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s2d3, +- RENAME_EXCHANGE)); ++ RENAME_EXCHANGE)); + ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s2d3, +- RENAME_EXCHANGE)); ++ RENAME_EXCHANGE)); + } + + TEST_F_FORK(layout1, rename_dir) +@@ -1707,8 +1737,8 @@ TEST_F_FORK(layout1, rename_dir) + }, + {}, + }; +- const int ruleset_fd = create_ruleset(_metadata, rules[0].access, +- rules); ++ const int ruleset_fd = ++ create_ruleset(_metadata, rules[0].access, rules); + + ASSERT_LE(0, ruleset_fd); + +@@ -1745,7 +1775,7 @@ TEST_F_FORK(layout1, rename_dir) + * directory removal. + */ + ASSERT_EQ(0, renameat2(AT_FDCWD, dir_s1d3, AT_FDCWD, file1_s1d2, +- RENAME_EXCHANGE)); ++ RENAME_EXCHANGE)); + ASSERT_EQ(0, unlink(dir_s1d3)); + ASSERT_EQ(0, mkdir(dir_s1d3, 0700)); + ASSERT_EQ(0, rename(file1_s1d2, dir_s1d3)); +@@ -1761,8 +1791,8 @@ TEST_F_FORK(layout1, remove_dir) + }, + {}, + }; +- const int ruleset_fd = create_ruleset(_metadata, rules[0].access, +- rules); ++ const int ruleset_fd = ++ create_ruleset(_metadata, rules[0].access, rules); + + ASSERT_LE(0, ruleset_fd); + +@@ -1798,8 +1828,8 @@ TEST_F_FORK(layout1, remove_file) + }, + {}, + }; +- const int ruleset_fd = create_ruleset(_metadata, rules[0].access, +- rules); ++ const int ruleset_fd = ++ create_ruleset(_metadata, rules[0].access, rules); + + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); +@@ -1814,7 +1844,8 @@ TEST_F_FORK(layout1, remove_file) + } + + static void test_make_file(struct __test_metadata *const _metadata, +- const __u64 access, const mode_t mode, const dev_t dev) ++ const __u64 access, const mode_t mode, ++ const dev_t dev) + { + const struct rule rules[] = { + { +@@ -1829,9 +1860,10 @@ static void test_make_file(struct __test + + ASSERT_EQ(0, unlink(file1_s1d1)); + ASSERT_EQ(0, unlink(file2_s1d1)); +- ASSERT_EQ(0, mknod(file2_s1d1, mode | 0400, dev)) { +- TH_LOG("Failed to make file \"%s\": %s", +- file2_s1d1, strerror(errno)); ++ ASSERT_EQ(0, mknod(file2_s1d1, mode | 0400, dev)) ++ { ++ TH_LOG("Failed to make file \"%s\": %s", file2_s1d1, ++ strerror(errno)); + }; + + ASSERT_EQ(0, unlink(file1_s1d2)); +@@ -1850,9 +1882,10 @@ static void test_make_file(struct __test + ASSERT_EQ(-1, rename(file2_s1d1, file1_s1d1)); + ASSERT_EQ(EACCES, errno); + +- ASSERT_EQ(0, mknod(file1_s1d2, mode | 0400, dev)) { +- TH_LOG("Failed to make file \"%s\": %s", +- file1_s1d2, strerror(errno)); ++ ASSERT_EQ(0, mknod(file1_s1d2, mode | 0400, dev)) ++ { ++ TH_LOG("Failed to make file \"%s\": %s", file1_s1d2, ++ strerror(errno)); + }; + ASSERT_EQ(0, link(file1_s1d2, file2_s1d2)); + ASSERT_EQ(0, unlink(file2_s1d2)); +@@ -1869,7 +1902,7 @@ TEST_F_FORK(layout1, make_char) + /* Creates a /dev/null device. */ + set_cap(_metadata, CAP_MKNOD); + test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_CHAR, S_IFCHR, +- makedev(1, 3)); ++ makedev(1, 3)); + } + + TEST_F_FORK(layout1, make_block) +@@ -1877,7 +1910,7 @@ TEST_F_FORK(layout1, make_block) + /* Creates a /dev/loop0 device. */ + set_cap(_metadata, CAP_MKNOD); + test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_BLOCK, S_IFBLK, +- makedev(7, 0)); ++ makedev(7, 0)); + } + + TEST_F_FORK(layout1, make_reg_1) +@@ -1909,8 +1942,8 @@ TEST_F_FORK(layout1, make_sym) + }, + {}, + }; +- const int ruleset_fd = create_ruleset(_metadata, rules[0].access, +- rules); ++ const int ruleset_fd = ++ create_ruleset(_metadata, rules[0].access, rules); + + ASSERT_LE(0, ruleset_fd); + +@@ -1954,8 +1987,8 @@ TEST_F_FORK(layout1, make_dir) + }, + {}, + }; +- const int ruleset_fd = create_ruleset(_metadata, rules[0].access, +- rules); ++ const int ruleset_fd = ++ create_ruleset(_metadata, rules[0].access, rules); + + ASSERT_LE(0, ruleset_fd); + +@@ -1974,12 +2007,12 @@ TEST_F_FORK(layout1, make_dir) + } + + static int open_proc_fd(struct __test_metadata *const _metadata, const int fd, +- const int open_flags) ++ const int open_flags) + { + static const char path_template[] = "/proc/self/fd/%d"; + char procfd_path[sizeof(path_template) + 10]; +- const int procfd_path_size = snprintf(procfd_path, sizeof(procfd_path), +- path_template, fd); ++ const int procfd_path_size = ++ snprintf(procfd_path, sizeof(procfd_path), path_template, fd); + + ASSERT_LT(procfd_path_size, sizeof(procfd_path)); + return open(procfd_path, open_flags); +@@ -1995,9 +2028,10 @@ TEST_F_FORK(layout1, proc_unlinked_file) + {}, + }; + int reg_fd, proc_fd; +- const int ruleset_fd = create_ruleset(_metadata, +- LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, rules); ++ const int ruleset_fd = create_ruleset( ++ _metadata, ++ LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE, ++ rules); + + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); +@@ -2014,9 +2048,10 @@ TEST_F_FORK(layout1, proc_unlinked_file) + ASSERT_EQ(0, close(proc_fd)); + + proc_fd = open_proc_fd(_metadata, reg_fd, O_RDWR | O_CLOEXEC); +- ASSERT_EQ(-1, proc_fd) { +- TH_LOG("Successfully opened /proc/self/fd/%d: %s", +- reg_fd, strerror(errno)); ++ ASSERT_EQ(-1, proc_fd) ++ { ++ TH_LOG("Successfully opened /proc/self/fd/%d: %s", reg_fd, ++ strerror(errno)); + } + ASSERT_EQ(EACCES, errno); + +@@ -2032,13 +2067,13 @@ TEST_F_FORK(layout1, proc_pipe) + { + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, ++ LANDLOCK_ACCESS_FS_WRITE_FILE, + }, + {}, + }; + /* Limits read and write access to files tied to the filesystem. */ +- const int ruleset_fd = create_ruleset(_metadata, rules[0].access, +- rules); ++ const int ruleset_fd = ++ create_ruleset(_metadata, rules[0].access, rules); + + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); +@@ -2050,7 +2085,8 @@ TEST_F_FORK(layout1, proc_pipe) + + /* Checks access to pipes through FD. */ + ASSERT_EQ(0, pipe2(pipe_fds, O_CLOEXEC)); +- ASSERT_EQ(1, write(pipe_fds[1], ".", 1)) { ++ ASSERT_EQ(1, write(pipe_fds[1], ".", 1)) ++ { + TH_LOG("Failed to write in pipe: %s", strerror(errno)); + } + ASSERT_EQ(1, read(pipe_fds[0], &buf, 1)); +@@ -2059,9 +2095,10 @@ TEST_F_FORK(layout1, proc_pipe) + /* Checks write access to pipe through /proc/self/fd . */ + proc_fd = open_proc_fd(_metadata, pipe_fds[1], O_WRONLY | O_CLOEXEC); + ASSERT_LE(0, proc_fd); +- ASSERT_EQ(1, write(proc_fd, ".", 1)) { ++ ASSERT_EQ(1, write(proc_fd, ".", 1)) ++ { + TH_LOG("Failed to write through /proc/self/fd/%d: %s", +- pipe_fds[1], strerror(errno)); ++ pipe_fds[1], strerror(errno)); + } + ASSERT_EQ(0, close(proc_fd)); + +@@ -2069,9 +2106,10 @@ TEST_F_FORK(layout1, proc_pipe) + proc_fd = open_proc_fd(_metadata, pipe_fds[0], O_RDONLY | O_CLOEXEC); + ASSERT_LE(0, proc_fd); + buf = '\0'; +- ASSERT_EQ(1, read(proc_fd, &buf, 1)) { ++ ASSERT_EQ(1, read(proc_fd, &buf, 1)) ++ { + TH_LOG("Failed to read through /proc/self/fd/%d: %s", +- pipe_fds[1], strerror(errno)); ++ pipe_fds[1], strerror(errno)); + } + ASSERT_EQ(0, close(proc_fd)); + +@@ -2292,8 +2330,8 @@ TEST_F_FORK(layout1_bind, same_content_s + ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_WRONLY)); + } + +-#define LOWER_BASE TMP_DIR "/lower" +-#define LOWER_DATA LOWER_BASE "/data" ++#define LOWER_BASE TMP_DIR "/lower" ++#define LOWER_DATA LOWER_BASE "/data" + static const char lower_fl1[] = LOWER_DATA "/fl1"; + static const char lower_dl1[] = LOWER_DATA "/dl1"; + static const char lower_dl1_fl2[] = LOWER_DATA "/dl1/fl2"; +@@ -2319,9 +2357,9 @@ static const char (*lower_sub_files[])[] + NULL, + }; + +-#define UPPER_BASE TMP_DIR "/upper" +-#define UPPER_DATA UPPER_BASE "/data" +-#define UPPER_WORK UPPER_BASE "/work" ++#define UPPER_BASE TMP_DIR "/upper" ++#define UPPER_DATA UPPER_BASE "/data" ++#define UPPER_WORK UPPER_BASE "/work" + static const char upper_fu1[] = UPPER_DATA "/fu1"; + static const char upper_du1[] = UPPER_DATA "/du1"; + static const char upper_du1_fu2[] = UPPER_DATA "/du1/fu2"; +@@ -2347,8 +2385,8 @@ static const char (*upper_sub_files[])[] + NULL, + }; + +-#define MERGE_BASE TMP_DIR "/merge" +-#define MERGE_DATA MERGE_BASE "/data" ++#define MERGE_BASE TMP_DIR "/merge" ++#define MERGE_DATA MERGE_BASE "/data" + static const char merge_fl1[] = MERGE_DATA "/fl1"; + static const char merge_dl1[] = MERGE_DATA "/dl1"; + static const char merge_dl1_fl2[] = MERGE_DATA "/dl1/fl2"; +@@ -2374,12 +2412,8 @@ static const char (*merge_base_directori + NULL, + }; + static const char (*merge_sub_files[])[] = { +- &merge_dl1_fl2, +- &merge_du1_fu2, +- &merge_do1_fo2, +- &merge_do1_fl3, +- &merge_do1_fu3, +- NULL, ++ &merge_dl1_fl2, &merge_du1_fu2, &merge_do1_fo2, ++ &merge_do1_fl3, &merge_do1_fu3, NULL, + }; + + /* +@@ -2455,9 +2489,8 @@ FIXTURE_SETUP(layout2_overlay) + set_cap(_metadata, CAP_SYS_ADMIN); + set_cap(_metadata, CAP_DAC_OVERRIDE); + ASSERT_EQ(0, mount("overlay", MERGE_DATA, "overlay", 0, +- "lowerdir=" LOWER_DATA +- ",upperdir=" UPPER_DATA +- ",workdir=" UPPER_WORK)); ++ "lowerdir=" LOWER_DATA ",upperdir=" UPPER_DATA ++ ",workdir=" UPPER_WORK)); + clear_cap(_metadata, CAP_DAC_OVERRIDE); + clear_cap(_metadata, CAP_SYS_ADMIN); + } +@@ -2524,9 +2557,9 @@ TEST_F_FORK(layout2_overlay, no_restrict + ASSERT_EQ(0, test_open(merge_do1_fu3, O_RDONLY)); + } + +-#define for_each_path(path_list, path_entry, i) \ +- for (i = 0, path_entry = *path_list[i]; path_list[i]; \ +- path_entry = *path_list[++i]) ++#define for_each_path(path_list, path_entry, i) \ ++ for (i = 0, path_entry = *path_list[i]; path_list[i]; \ ++ path_entry = *path_list[++i]) + + TEST_F_FORK(layout2_overlay, same_content_different_file) + { +@@ -2622,27 +2655,27 @@ TEST_F_FORK(layout2_overlay, same_conten + { + .path = merge_dl1_fl2, + .access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, ++ LANDLOCK_ACCESS_FS_WRITE_FILE, + }, + { + .path = merge_du1_fu2, + .access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, ++ LANDLOCK_ACCESS_FS_WRITE_FILE, + }, + { + .path = merge_do1_fo2, + .access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, ++ LANDLOCK_ACCESS_FS_WRITE_FILE, + }, + { + .path = merge_do1_fl3, + .access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, ++ LANDLOCK_ACCESS_FS_WRITE_FILE, + }, + { + .path = merge_do1_fu3, + .access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, ++ LANDLOCK_ACCESS_FS_WRITE_FILE, + }, + {}, + }; +@@ -2650,7 +2683,7 @@ TEST_F_FORK(layout2_overlay, same_conten + { + .path = MERGE_DATA, + .access = LANDLOCK_ACCESS_FS_READ_FILE | +- LANDLOCK_ACCESS_FS_WRITE_FILE, ++ LANDLOCK_ACCESS_FS_WRITE_FILE, + }, + {}, + }; +@@ -2670,7 +2703,8 @@ TEST_F_FORK(layout2_overlay, same_conten + ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY)); + } + for_each_path(lower_base_directories, path_entry, i) { +- ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY | O_DIRECTORY)); ++ ASSERT_EQ(EACCES, ++ test_open(path_entry, O_RDONLY | O_DIRECTORY)); + } + for_each_path(lower_sub_files, path_entry, i) { + ASSERT_EQ(0, test_open(path_entry, O_RDONLY)); +@@ -2682,7 +2716,8 @@ TEST_F_FORK(layout2_overlay, same_conten + ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY)); + } + for_each_path(upper_base_directories, path_entry, i) { +- ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY | O_DIRECTORY)); ++ ASSERT_EQ(EACCES, ++ test_open(path_entry, O_RDONLY | O_DIRECTORY)); + } + for_each_path(upper_sub_files, path_entry, i) { + ASSERT_EQ(0, test_open(path_entry, O_RDONLY)); +@@ -2767,7 +2802,8 @@ TEST_F_FORK(layout2_overlay, same_conten + ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR)); + } + for_each_path(merge_base_directories, path_entry, i) { +- ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY | O_DIRECTORY)); ++ ASSERT_EQ(EACCES, ++ test_open(path_entry, O_RDONLY | O_DIRECTORY)); + } + for_each_path(merge_sub_files, path_entry, i) { + ASSERT_EQ(0, test_open(path_entry, O_RDWR)); +@@ -2792,7 +2828,8 @@ TEST_F_FORK(layout2_overlay, same_conten + ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR)); + } + for_each_path(merge_base_directories, path_entry, i) { +- ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY | O_DIRECTORY)); ++ ASSERT_EQ(EACCES, ++ test_open(path_entry, O_RDONLY | O_DIRECTORY)); + } + for_each_path(merge_sub_files, path_entry, i) { + ASSERT_EQ(0, test_open(path_entry, O_RDWR)); +--- a/tools/testing/selftests/landlock/ptrace_test.c ++++ b/tools/testing/selftests/landlock/ptrace_test.c +@@ -26,9 +26,10 @@ static void create_domain(struct __test_ + .handled_access_fs = LANDLOCK_ACCESS_FS_MAKE_BLOCK, + }; + +- ruleset_fd = landlock_create_ruleset(&ruleset_attr, +- sizeof(ruleset_attr), 0); +- EXPECT_LE(0, ruleset_fd) { ++ ruleset_fd = ++ landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); ++ EXPECT_LE(0, ruleset_fd) ++ { + TH_LOG("Failed to create a ruleset: %s", strerror(errno)); + } + EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); +@@ -43,7 +44,7 @@ static int test_ptrace_read(const pid_t + int procenv_path_size, fd; + + procenv_path_size = snprintf(procenv_path, sizeof(procenv_path), +- path_template, pid); ++ path_template, pid); + if (procenv_path_size >= sizeof(procenv_path)) + return E2BIG; + +@@ -63,7 +64,8 @@ static int test_ptrace_read(const pid_t + FIXTURE(hierarchy) {}; + /* clang-format on */ + +-FIXTURE_VARIANT(hierarchy) { ++FIXTURE_VARIANT(hierarchy) ++{ + const bool domain_both; + const bool domain_parent; + const bool domain_child; +@@ -217,10 +219,12 @@ FIXTURE_VARIANT_ADD(hierarchy, deny_with + }; + + FIXTURE_SETUP(hierarchy) +-{ } ++{ ++} + + FIXTURE_TEARDOWN(hierarchy) +-{ } ++{ ++} + + /* Test PTRACE_TRACEME and PTRACE_ATTACH for parent and child. */ + TEST_F(hierarchy, trace) +@@ -348,7 +352,7 @@ TEST_F(hierarchy, trace) + ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); + ASSERT_EQ(child, waitpid(child, &status, 0)); + if (WIFSIGNALED(status) || !WIFEXITED(status) || +- WEXITSTATUS(status) != EXIT_SUCCESS) ++ WEXITSTATUS(status) != EXIT_SUCCESS) + _metadata->passed = 0; + } + diff --git a/queue-5.18/selftests-landlock-fully-test-file-rename-with-remove-access.patch b/queue-5.18/selftests-landlock-fully-test-file-rename-with-remove-access.patch new file mode 100644 index 00000000000..c5103354b11 --- /dev/null +++ b/queue-5.18/selftests-landlock-fully-test-file-rename-with-remove-access.patch @@ -0,0 +1,125 @@ +From 6a1bdd4a0bfc30fa4fa2b3a979e6525f28996db9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:08:16 +0200 +Subject: selftests/landlock: Fully test file rename with "remove" access +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 6a1bdd4a0bfc30fa4fa2b3a979e6525f28996db9 upstream. + +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 +Link: https://lore.kernel.org/r/20220506160820.524344-7-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/landlock/fs_test.c | 41 ++++++++++++++++++++++++++--- + 1 file changed, 37 insertions(+), 4 deletions(-) + +--- 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 diff --git a/queue-5.18/selftests-landlock-make-tests-build-with-old-libc.patch b/queue-5.18/selftests-landlock-make-tests-build-with-old-libc.patch new file mode 100644 index 00000000000..55bfc593fec --- /dev/null +++ b/queue-5.18/selftests-landlock-make-tests-build-with-old-libc.patch @@ -0,0 +1,96 @@ +From 87129ef13603ae46c82bcd09eed948acf0506dbb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:08:12 +0200 +Subject: selftests/landlock: Make tests build with old libc +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 87129ef13603ae46c82bcd09eed948acf0506dbb upstream. + +Replace SYS_ with __NR_. Using the __NR_ +notation, provided by UAPI, is useful to build tests on systems without +the SYS_ 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 +Link: https://lore.kernel.org/r/20220506160820.524344-3-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/landlock/fs_test.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +--- 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_n + 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); diff --git a/queue-5.18/selftests-landlock-normalize-array-assignment.patch b/queue-5.18/selftests-landlock-normalize-array-assignment.patch new file mode 100644 index 00000000000..73699af940c --- /dev/null +++ b/queue-5.18/selftests-landlock-normalize-array-assignment.patch @@ -0,0 +1,519 @@ +From 135464f9d29c5b306d7201220f1d00dab30fea89 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:05:10 +0200 +Subject: selftests/landlock: Normalize array assignment +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 135464f9d29c5b306d7201220f1d00dab30fea89 upstream. + +Add a comma after each array value to make clang-format keep the +current array formatting. See the following commit. + +Automatically modified with: +sed -i 's/\t\({}\|NULL\)$/\0,/' tools/testing/selftests/landlock/fs_test.c + +Link: https://lore.kernel.org/r/20220506160513.523257-5-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/landlock/fs_test.c | 112 ++++++++++++++--------------- + 1 file changed, 56 insertions(+), 56 deletions(-) + +--- a/tools/testing/selftests/landlock/fs_test.c ++++ b/tools/testing/selftests/landlock/fs_test.c +@@ -514,7 +514,7 @@ TEST_F_FORK(layout1, proc_nsfs) + .access = LANDLOCK_ACCESS_FS_READ_FILE | + LANDLOCK_ACCESS_FS_WRITE_FILE, + }, +- {} ++ {}, + }; + struct landlock_path_beneath_attr path_beneath; + const int ruleset_fd = create_ruleset(_metadata, rules[0].access | +@@ -560,7 +560,7 @@ TEST_F_FORK(layout1, unpriv) { + .path = dir_s1d2, + .access = ACCESS_RO, + }, +- {} ++ {}, + }; + int ruleset_fd; + +@@ -588,7 +588,7 @@ TEST_F_FORK(layout1, effective_access) + .access = LANDLOCK_ACCESS_FS_READ_FILE | + LANDLOCK_ACCESS_FS_WRITE_FILE, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules); + char buf; +@@ -635,7 +635,7 @@ TEST_F_FORK(layout1, unhandled_access) + .path = dir_s1d2, + .access = ACCESS_RO, + }, +- {} ++ {}, + }; + /* Here, we only handle read accesses, not write accesses. */ + const int ruleset_fd = create_ruleset(_metadata, ACCESS_RO, rules); +@@ -669,7 +669,7 @@ TEST_F_FORK(layout1, ruleset_overlap) + .access = LANDLOCK_ACCESS_FS_READ_FILE | + LANDLOCK_ACCESS_FS_READ_DIR, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules); + +@@ -703,14 +703,14 @@ TEST_F_FORK(layout1, non_overlapping_acc + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_MAKE_REG, + }, +- {} ++ {}, + }; + const struct rule layer2[] = { + { + .path = dir_s1d3, + .access = LANDLOCK_ACCESS_FS_REMOVE_FILE, + }, +- {} ++ {}, + }; + int ruleset_fd; + +@@ -767,7 +767,7 @@ TEST_F_FORK(layout1, interleaved_masked_ + .path = file1_s1d3, + .access = LANDLOCK_ACCESS_FS_READ_FILE, + }, +- {} ++ {}, + }; + /* First rule with write restrictions. */ + const struct rule layer2_read_write[] = { +@@ -782,7 +782,7 @@ TEST_F_FORK(layout1, interleaved_masked_ + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_WRITE_FILE, + }, +- {} ++ {}, + }; + const struct rule layer3_read[] = { + /* Allows read access via its great-grandparent directory. */ +@@ -790,7 +790,7 @@ TEST_F_FORK(layout1, interleaved_masked_ + .path = dir_s1d1, + .access = LANDLOCK_ACCESS_FS_READ_FILE, + }, +- {} ++ {}, + }; + const struct rule layer4_read_write[] = { + /* +@@ -801,7 +801,7 @@ TEST_F_FORK(layout1, interleaved_masked_ + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_READ_FILE, + }, +- {} ++ {}, + }; + const struct rule layer5_read[] = { + /* +@@ -812,7 +812,7 @@ TEST_F_FORK(layout1, interleaved_masked_ + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_READ_FILE, + }, +- {} ++ {}, + }; + const struct rule layer6_execute[] = { + /* +@@ -823,7 +823,7 @@ TEST_F_FORK(layout1, interleaved_masked_ + .path = dir_s2d1, + .access = LANDLOCK_ACCESS_FS_EXECUTE, + }, +- {} ++ {}, + }; + const struct rule layer7_read_write[] = { + /* +@@ -834,7 +834,7 @@ TEST_F_FORK(layout1, interleaved_masked_ + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_WRITE_FILE, + }, +- {} ++ {}, + }; + int ruleset_fd; + +@@ -932,7 +932,7 @@ TEST_F_FORK(layout1, inherit_subset) + .access = LANDLOCK_ACCESS_FS_READ_FILE | + LANDLOCK_ACCESS_FS_READ_DIR, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules); + +@@ -1048,7 +1048,7 @@ TEST_F_FORK(layout1, inherit_superset) + .path = dir_s1d3, + .access = ACCESS_RO, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules); + +@@ -1084,7 +1084,7 @@ TEST_F_FORK(layout1, max_layers) + .path = dir_s1d2, + .access = ACCESS_RO, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules); + +@@ -1146,7 +1146,7 @@ TEST_F_FORK(layout1, rule_on_mountpoint) + .path = dir_s3d2, + .access = ACCESS_RO, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules); + +@@ -1175,7 +1175,7 @@ TEST_F_FORK(layout1, rule_over_mountpoin + .path = dir_s3d1, + .access = ACCESS_RO, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules); + +@@ -1203,7 +1203,7 @@ TEST_F_FORK(layout1, rule_over_root_allo + .path = "/", + .access = ACCESS_RO, + }, +- {} ++ {}, + }; + int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules); + +@@ -1233,7 +1233,7 @@ TEST_F_FORK(layout1, rule_over_root_deny + .path = "/", + .access = LANDLOCK_ACCESS_FS_READ_FILE, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules); + +@@ -1253,7 +1253,7 @@ TEST_F_FORK(layout1, rule_inside_mount_n + .path = "s3d3", + .access = ACCESS_RO, + }, +- {} ++ {}, + }; + int ruleset_fd; + +@@ -1280,7 +1280,7 @@ TEST_F_FORK(layout1, mount_and_pivot) + .path = dir_s3d2, + .access = ACCESS_RO, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules); + +@@ -1303,7 +1303,7 @@ TEST_F_FORK(layout1, move_mount) + .path = dir_s3d2, + .access = ACCESS_RO, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules); + +@@ -1344,7 +1344,7 @@ TEST_F_FORK(layout1, release_inodes) + .path = dir_s3d3, + .access = ACCESS_RO, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules); + +@@ -1382,7 +1382,7 @@ static void test_relative_path(struct __ + .path = TMP_DIR, + .access = ACCESS_RO, + }, +- {} ++ {}, + }; + const struct rule layer2_subs[] = { + { +@@ -1393,7 +1393,7 @@ static void test_relative_path(struct __ + .path = dir_s2d2, + .access = ACCESS_RO, + }, +- {} ++ {}, + }; + int dirfd, ruleset_fd; + +@@ -1558,7 +1558,7 @@ TEST_F_FORK(layout1, execute) + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_EXECUTE, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, rules[0].access, + rules); +@@ -1591,7 +1591,7 @@ TEST_F_FORK(layout1, link) + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_MAKE_REG, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, rules[0].access, + rules); +@@ -1628,7 +1628,7 @@ TEST_F_FORK(layout1, rename_file) + .path = dir_s2d2, + .access = LANDLOCK_ACCESS_FS_REMOVE_FILE, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, rules[0].access, + rules); +@@ -1705,7 +1705,7 @@ TEST_F_FORK(layout1, rename_dir) + .path = dir_s2d1, + .access = LANDLOCK_ACCESS_FS_REMOVE_DIR, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, rules[0].access, + rules); +@@ -1759,7 +1759,7 @@ TEST_F_FORK(layout1, remove_dir) + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_REMOVE_DIR, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, rules[0].access, + rules); +@@ -1796,7 +1796,7 @@ TEST_F_FORK(layout1, remove_file) + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_REMOVE_FILE, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, rules[0].access, + rules); +@@ -1821,7 +1821,7 @@ static void test_make_file(struct __test + .path = dir_s1d2, + .access = access, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, access, rules); + +@@ -1907,7 +1907,7 @@ TEST_F_FORK(layout1, make_sym) + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_MAKE_SYM, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, rules[0].access, + rules); +@@ -1952,7 +1952,7 @@ TEST_F_FORK(layout1, make_dir) + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_MAKE_DIR, + }, +- {} ++ {}, + }; + const int ruleset_fd = create_ruleset(_metadata, rules[0].access, + rules); +@@ -1992,7 +1992,7 @@ TEST_F_FORK(layout1, proc_unlinked_file) + .path = file1_s1d2, + .access = LANDLOCK_ACCESS_FS_READ_FILE, + }, +- {} ++ {}, + }; + int reg_fd, proc_fd; + const int ruleset_fd = create_ruleset(_metadata, +@@ -2034,7 +2034,7 @@ TEST_F_FORK(layout1, proc_pipe) + .access = LANDLOCK_ACCESS_FS_READ_FILE | + LANDLOCK_ACCESS_FS_WRITE_FILE, + }, +- {} ++ {}, + }; + /* Limits read and write access to files tied to the filesystem. */ + const int ruleset_fd = create_ruleset(_metadata, rules[0].access, +@@ -2171,7 +2171,7 @@ TEST_F_FORK(layout1_bind, same_content_s + .path = dir_s2d1, + .access = ACCESS_RW, + }, +- {} ++ {}, + }; + /* + * Sets access rights on the same bind-mounted directories. The result +@@ -2187,7 +2187,7 @@ TEST_F_FORK(layout1_bind, same_content_s + .path = dir_s2d2, + .access = ACCESS_RW, + }, +- {} ++ {}, + }; + /* Only allow read-access to the s1d3 hierarchies. */ + const struct rule layer3_source[] = { +@@ -2195,7 +2195,7 @@ TEST_F_FORK(layout1_bind, same_content_s + .path = dir_s1d3, + .access = LANDLOCK_ACCESS_FS_READ_FILE, + }, +- {} ++ {}, + }; + /* Removes all access rights. */ + const struct rule layer4_destination[] = { +@@ -2203,7 +2203,7 @@ TEST_F_FORK(layout1_bind, same_content_s + .path = bind_file1_s1d3, + .access = LANDLOCK_ACCESS_FS_WRITE_FILE, + }, +- {} ++ {}, + }; + int ruleset_fd; + +@@ -2305,18 +2305,18 @@ static const char lower_do1_fl3[] = LOWE + static const char (*lower_base_files[])[] = { + &lower_fl1, + &lower_fo1, +- NULL ++ NULL, + }; + static const char (*lower_base_directories[])[] = { + &lower_dl1, + &lower_do1, +- NULL ++ NULL, + }; + static const char (*lower_sub_files[])[] = { + &lower_dl1_fl2, + &lower_do1_fo2, + &lower_do1_fl3, +- NULL ++ NULL, + }; + + #define UPPER_BASE TMP_DIR "/upper" +@@ -2333,18 +2333,18 @@ static const char upper_do1_fu3[] = UPPE + static const char (*upper_base_files[])[] = { + &upper_fu1, + &upper_fo1, +- NULL ++ NULL, + }; + static const char (*upper_base_directories[])[] = { + &upper_du1, + &upper_do1, +- NULL ++ NULL, + }; + static const char (*upper_sub_files[])[] = { + &upper_du1_fu2, + &upper_do1_fo2, + &upper_do1_fu3, +- NULL ++ NULL, + }; + + #define MERGE_BASE TMP_DIR "/merge" +@@ -2365,13 +2365,13 @@ static const char (*merge_base_files[])[ + &merge_fl1, + &merge_fu1, + &merge_fo1, +- NULL ++ NULL, + }; + static const char (*merge_base_directories[])[] = { + &merge_dl1, + &merge_du1, + &merge_do1, +- NULL ++ NULL, + }; + static const char (*merge_sub_files[])[] = { + &merge_dl1_fl2, +@@ -2379,7 +2379,7 @@ static const char (*merge_sub_files[])[] + &merge_do1_fo2, + &merge_do1_fl3, + &merge_do1_fu3, +- NULL ++ NULL, + }; + + /* +@@ -2544,7 +2544,7 @@ TEST_F_FORK(layout2_overlay, same_conten + .path = MERGE_BASE, + .access = ACCESS_RW, + }, +- {} ++ {}, + }; + const struct rule layer2_data[] = { + { +@@ -2559,7 +2559,7 @@ TEST_F_FORK(layout2_overlay, same_conten + .path = MERGE_DATA, + .access = ACCESS_RW, + }, +- {} ++ {}, + }; + /* Sets access right on directories inside both layers. */ + const struct rule layer3_subdirs[] = { +@@ -2591,7 +2591,7 @@ TEST_F_FORK(layout2_overlay, same_conten + .path = merge_do1, + .access = ACCESS_RW, + }, +- {} ++ {}, + }; + /* Tighten access rights to the files. */ + const struct rule layer4_files[] = { +@@ -2644,7 +2644,7 @@ TEST_F_FORK(layout2_overlay, same_conten + .access = LANDLOCK_ACCESS_FS_READ_FILE | + LANDLOCK_ACCESS_FS_WRITE_FILE, + }, +- {} ++ {}, + }; + const struct rule layer5_merge_only[] = { + { +@@ -2652,7 +2652,7 @@ TEST_F_FORK(layout2_overlay, same_conten + .access = LANDLOCK_ACCESS_FS_READ_FILE | + LANDLOCK_ACCESS_FS_WRITE_FILE, + }, +- {} ++ {}, + }; + int ruleset_fd; + size_t i; diff --git a/queue-5.18/selftests-landlock-test-landlock_create_ruleset-2-argument-check-ordering.patch b/queue-5.18/selftests-landlock-test-landlock_create_ruleset-2-argument-check-ordering.patch new file mode 100644 index 00000000000..30a97fed970 --- /dev/null +++ b/queue-5.18/selftests-landlock-test-landlock_create_ruleset-2-argument-check-ordering.patch @@ -0,0 +1,73 @@ +From 6533d0c3a86ee1cc74ff37ac92ca597deb87015c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= +Date: Fri, 6 May 2022 18:08:20 +0200 +Subject: selftests/landlock: Test landlock_create_ruleset(2) argument check ordering +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +commit 6533d0c3a86ee1cc74ff37ac92ca597deb87015c upstream. + +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. + +Link: https://lore.kernel.org/r/20220506160820.524344-11-mic@digikod.net +Cc: stable@vger.kernel.org +Signed-off-by: Mickaël Salaün +Signed-off-by: Greg Kroah-Hartman +--- + tools/testing/selftests/landlock/base_test.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +--- 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. */ diff --git a/queue-5.18/series b/queue-5.18/series index 92e4dfd21eb..59857296646 100644 --- a/queue-5.18/series +++ b/queue-5.18/series @@ -768,3 +768,24 @@ dlm-fix-missing-lkb-refcount-handling.patch ocfs2-dlmfs-fix-error-handling-of-user_dlm_destroy_lock.patch scsi-dc395x-fix-a-missing-check-on-list-iterator.patch scsi-ufs-qcom-add-a-readl-to-make-sure-ref_clk-gets-enabled.patch +landlock-add-clang-format-exceptions.patch +landlock-format-with-clang-format.patch +selftests-landlock-add-clang-format-exceptions.patch +selftests-landlock-normalize-array-assignment.patch +selftests-landlock-format-with-clang-format.patch +samples-landlock-add-clang-format-exceptions.patch +samples-landlock-format-with-clang-format.patch +landlock-fix-landlock_add_rule-2-documentation.patch +selftests-landlock-make-tests-build-with-old-libc.patch +selftests-landlock-extend-tests-for-minimal-valid-attribute-size.patch +selftests-landlock-add-tests-for-unknown-access-rights.patch +selftests-landlock-extend-access-right-tests-to-directories.patch +selftests-landlock-fully-test-file-rename-with-remove-access.patch +selftests-landlock-add-tests-for-o_path.patch +landlock-change-landlock_add_rule-2-argument-check-ordering.patch +landlock-change-landlock_restrict_self-2-check-ordering.patch +selftests-landlock-test-landlock_create_ruleset-2-argument-check-ordering.patch +landlock-define-access_mask_t-to-enforce-a-consistent-access-mask-size.patch +landlock-reduce-the-maximum-number-of-layers-to-16.patch +landlock-create-find_rule-from-unmask_layers.patch +landlock-fix-same-layer-rule-unions.patch