[PATCH v2 1/3] landlock: Require LANDLOCK_ACCESS_FS_MAKE_WHITEOUT for RENAME_WHITEOUT
Mickaël Salaün
mic at digikod.net
Tue Jun 9 16:09:51 UTC 2026
On Wed, May 13, 2026 at 06:05:50PM +0200, Günther Noack wrote:
> renameat2(2) with the RENAME_WHITEOUT flag places a whiteout character
> device file in the source file location in place of the moved file.
> This creates a directory entry even in cases where all
> LANDLOCK_ACCESS_FS_MAKE_* rights are denied.
>
> Introduce the LANDLOCK_ACCESS_FS_MAKE_WHITEOUT right, which is checked
> for the origin directory if RENAME_WHITEOUT is passed.
>
> This does not affect normal renames within layered OverlayFS mounts:
> When OverlayFS invokes rename with RENAME_WHITEOUT as part of a
> "normal" rename operation, it does so in ovl_rename() using the
> credentials that were set at the time of mounting the OverlayFS.
>
> Bump the Landlock ABI version to 10.
>
> Suggested-by: Christian Brauner <brauner at kernel.org>
> Suggested-by: Mickaël Salaün <mic at digikod.net>
> Signed-off-by: Günther Noack <gnoack at google.com>
> ---
> include/uapi/linux/landlock.h | 3 +++
> security/landlock/audit.c | 1 +
> security/landlock/fs.c | 15 +++++++++++++++
> security/landlock/limits.h | 2 +-
> security/landlock/syscalls.c | 2 +-
> tools/testing/selftests/landlock/base_test.c | 4 ++--
> tools/testing/selftests/landlock/fs_test.c | 5 +++--
> 7 files changed, 26 insertions(+), 6 deletions(-)
>
> diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h
> index 10a346e55e95..1f8a1d6d25f1 100644
> --- a/include/uapi/linux/landlock.h
> +++ b/include/uapi/linux/landlock.h
> @@ -328,6 +328,8 @@ struct landlock_net_port_attr {
> *
> * If multiple requirements are not met, the ``EACCES`` error code takes
> * precedence over ``EXDEV``.
> + * - %LANDLOCK_ACCESS_FS_MAKE_WHITEOUT: Create a whiteout object through
> + * :manpage:`rename(2)` with ``RENAME_WHITEOUT``.
> *
> * .. warning::
> *
> @@ -356,6 +358,7 @@ struct landlock_net_port_attr {
> #define LANDLOCK_ACCESS_FS_TRUNCATE (1ULL << 14)
> #define LANDLOCK_ACCESS_FS_IOCTL_DEV (1ULL << 15)
> #define LANDLOCK_ACCESS_FS_RESOLVE_UNIX (1ULL << 16)
> +#define LANDLOCK_ACCESS_FS_MAKE_WHITEOUT (1ULL << 17)
> /* clang-format on */
>
> /**
> diff --git a/security/landlock/audit.c b/security/landlock/audit.c
> index 8d0edf94037d..09c97083f599 100644
> --- a/security/landlock/audit.c
> +++ b/security/landlock/audit.c
> @@ -38,6 +38,7 @@ static const char *const fs_access_strings[] = {
> [BIT_INDEX(LANDLOCK_ACCESS_FS_TRUNCATE)] = "fs.truncate",
> [BIT_INDEX(LANDLOCK_ACCESS_FS_IOCTL_DEV)] = "fs.ioctl_dev",
> [BIT_INDEX(LANDLOCK_ACCESS_FS_RESOLVE_UNIX)] = "fs.resolve_unix",
> + [BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_WHITEOUT)] = "fs.make_whiteout",
> };
>
> static_assert(ARRAY_SIZE(fs_access_strings) == LANDLOCK_NUM_ACCESS_FS);
> diff --git a/security/landlock/fs.c b/security/landlock/fs.c
> index c1ecfe239032..09de6ba5c3a3 100644
> --- a/security/landlock/fs.c
> +++ b/security/landlock/fs.c
> @@ -1519,6 +1519,21 @@ static int hook_path_rename(const struct path *const old_dir,
> const unsigned int flags)
> {
> /* old_dir refers to old_dentry->d_parent and new_dir->mnt */
> + if (flags & RENAME_WHITEOUT) {
> + int err;
> +
> + /*
> + * Rename with RENAME_WHITEOUT creates a whiteout object in the
> + * old location, so we check the access right for creating that.
> + *
> + * See Documentation/filesystems/overlayfs.rst and renameat2(2).
> + */
> + err = current_check_access_path(
> + old_dir, LANDLOCK_ACCESS_FS_MAKE_WHITEOUT);
We should not need a second path walk, even if whiteouts are rare.
Please propose another way.
> + if (err)
> + return err;
> + }
> +
> return current_check_refer_path(old_dentry, new_dir, new_dentry, true,
> !!(flags & RENAME_EXCHANGE));
> }
> diff --git a/security/landlock/limits.h b/security/landlock/limits.h
> index b454ad73b15e..e59378e8e897 100644
> --- a/security/landlock/limits.h
> +++ b/security/landlock/limits.h
> @@ -19,7 +19,7 @@
> #define LANDLOCK_MAX_NUM_LAYERS 16
> #define LANDLOCK_MAX_NUM_RULES U32_MAX
>
> -#define LANDLOCK_LAST_ACCESS_FS LANDLOCK_ACCESS_FS_RESOLVE_UNIX
> +#define LANDLOCK_LAST_ACCESS_FS LANDLOCK_ACCESS_FS_MAKE_WHITEOUT
> #define LANDLOCK_MASK_ACCESS_FS ((LANDLOCK_LAST_ACCESS_FS << 1) - 1)
> #define LANDLOCK_NUM_ACCESS_FS __const_hweight64(LANDLOCK_MASK_ACCESS_FS)
>
> diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c
> index accfd2e5a0cd..d45469d5d464 100644
> --- a/security/landlock/syscalls.c
> +++ b/security/landlock/syscalls.c
> @@ -166,7 +166,7 @@ static const struct file_operations ruleset_fops = {
> * If the change involves a fix that requires userspace awareness, also update
> * the errata documentation in Documentation/userspace-api/landlock.rst .
> */
> -const int landlock_abi_version = 9;
> +const int landlock_abi_version = 10;
>
> /**
> * sys_landlock_create_ruleset - Create a new ruleset
> diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/selftests/landlock/base_test.c
> index 30d37234086c..6c8113c2ded1 100644
> --- a/tools/testing/selftests/landlock/base_test.c
> +++ b/tools/testing/selftests/landlock/base_test.c
> @@ -76,8 +76,8 @@ TEST(abi_version)
> const struct landlock_ruleset_attr ruleset_attr = {
> .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE,
> };
> - ASSERT_EQ(9, landlock_create_ruleset(NULL, 0,
> - LANDLOCK_CREATE_RULESET_VERSION));
> + ASSERT_EQ(10, landlock_create_ruleset(NULL, 0,
> + LANDLOCK_CREATE_RULESET_VERSION));
>
> ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0,
> LANDLOCK_CREATE_RULESET_VERSION));
> diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
> index cdb47fc1fc0a..53d1b659849f 100644
> --- a/tools/testing/selftests/landlock/fs_test.c
> +++ b/tools/testing/selftests/landlock/fs_test.c
> @@ -579,7 +579,7 @@ TEST_F_FORK(layout1, inval)
> LANDLOCK_ACCESS_FS_IOCTL_DEV | \
> LANDLOCK_ACCESS_FS_RESOLVE_UNIX)
>
> -#define ACCESS_LAST LANDLOCK_ACCESS_FS_RESOLVE_UNIX
> +#define ACCESS_LAST LANDLOCK_ACCESS_FS_MAKE_WHITEOUT
>
> #define ACCESS_ALL ( \
> ACCESS_FILE | \
> @@ -593,7 +593,8 @@ TEST_F_FORK(layout1, inval)
> LANDLOCK_ACCESS_FS_MAKE_FIFO | \
> LANDLOCK_ACCESS_FS_MAKE_BLOCK | \
> LANDLOCK_ACCESS_FS_MAKE_SYM | \
> - LANDLOCK_ACCESS_FS_REFER)
> + LANDLOCK_ACCESS_FS_REFER | \
> + LANDLOCK_ACCESS_FS_MAKE_WHITEOUT)
>
> /* clang-format on */
>
> --
> 2.54.0.563.g4f69b47b94-goog
>
>
More information about the Linux-security-module-archive
mailing list