From 1cafd632b62c3c1177fb3565f81f9f7a0918e062 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Thu, 11 Apr 2024 18:54:27 +1200 Subject: [PATCH] Support landlock syscalls Resolves #3722 --- CMakeLists.txt | 1 + src/syscalls.py | 6 +++--- src/test/landlock.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 src/test/landlock.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 376705dd551..9838bbcdd05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1081,6 +1081,7 @@ set(BASIC_TESTS keyctl kill_newborn kill_ptracee + landlock large_hole large_write_deadlock legacy_ugid diff --git a/src/syscalls.py b/src/syscalls.py index 4514f7d3b19..4b13178630f 100644 --- a/src/syscalls.py +++ b/src/syscalls.py @@ -1736,9 +1736,9 @@ def __init__(self, **kwargs): epoll_pwait2 = IrregularEmulatedSyscall(all=441) mount_setattr = UnsupportedSyscall(all=442) quotactl_fd = UnsupportedSyscall(all=443) -landlock_create_ruleset = UnsupportedSyscall(all=444) -landlock_add_rule = UnsupportedSyscall(all=445) -landlock_restrict_self = UnsupportedSyscall(all=446) +landlock_create_ruleset = EmulatedSyscall(all=444) +landlock_add_rule = EmulatedSyscall(all=445) +landlock_restrict_self = EmulatedSyscall(all=446) memfd_secret = UnsupportedSyscall(all=447) process_mrelease = UnsupportedSyscall(all=448) futex_waitv = UnsupportedSyscall(all=449) diff --git a/src/test/landlock.c b/src/test/landlock.c new file mode 100644 index 00000000000..4e47b35801d --- /dev/null +++ b/src/test/landlock.c @@ -0,0 +1,47 @@ +/* -*- Mode: C; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil; -*- */ + +#include "util.h" + +#define LANDLOCK_RULE_PATH_BENEATH 1 + +#define LANDLOCK_ACCESS_FS_READ_DIR 8 + +struct landlock_ruleset_attr { + uint64_t handled_access_fs; +}; + +struct landlock_path_beneath_attr { + uint64_t allowed_access; + int32_t parent_fd; +} __attribute__((packed)); + +int main(void) { + struct landlock_ruleset_attr ruleset = { LANDLOCK_ACCESS_FS_READ_DIR }; + int ruleset_fd = syscall(RR_landlock_create_ruleset, + &ruleset, sizeof(struct landlock_ruleset_attr), + 0); + if (ruleset_fd < 0 && errno == ENOSYS) { + atomic_puts("landlock not supported, skipping test"); + atomic_puts("EXIT-SUCCESS"); + return 0; + } + test_assert(ruleset_fd >= 0); + + int root_fd = open("/", O_PATH); + test_assert(root_fd >= 0); + + struct landlock_path_beneath_attr rule = + { LANDLOCK_ACCESS_FS_READ_DIR, root_fd }; + int ret = syscall(RR_landlock_add_rule, ruleset_fd, + LANDLOCK_RULE_PATH_BENEATH, &rule, 0); + test_assert(ret == 0); + + ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + test_assert(ret == 0); + + ret = syscall(RR_landlock_restrict_self, ruleset_fd, 0); + test_assert(ret == 0); + + atomic_puts("EXIT-SUCCESS"); + return 0; +}