diff --git a/CMakeLists.txt b/CMakeLists.txt index 3091eca3..d24fd9a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2074,6 +2074,7 @@ option(XZ_TOOL_XZ "Build and install the xz command line tool" ON) if(XZ_TOOL_XZ) add_executable(xz + src/common/my_landlock.h src/common/mythread.h src/common/sysdefs.h src/common/tuklib_common.h diff --git a/src/xz/sandbox.c b/src/xz/sandbox.c index 5a12f69b..265d4bb7 100644 --- a/src/xz/sandbox.c +++ b/src/xz/sandbox.c @@ -115,26 +115,7 @@ sandbox_enable_strict_if_allowed(int src_fd lzma_attribute((__unused__)), // Landlock // ////////////// -#include -#include -#include - - -// Highest Landlock ABI version supported by this file: -// - For ABI versions 1-3 we don't need anything from -// that isn't part of version 1. -// - For ABI version 4 we need the larger struct landlock_ruleset_attr -// with the handled_access_net member. That is bundled with the macros -// LANDLOCK_ACCESS_NET_BIND_TCP and LANDLOCK_ACCESS_NET_CONNECT_TCP. -#ifdef LANDLOCK_ACCESS_NET_BIND_TCP -# define LANDLOCK_ABI_MAX 4 -#else -# define LANDLOCK_ABI_MAX 3 -#endif - - -/// Landlock ABI version supported by the kernel -static int landlock_abi; +#include "my_landlock.h" // The required_rights should have those bits set that must not be restricted. @@ -144,40 +125,19 @@ static int landlock_abi; static void enable_landlock(uint64_t required_rights) { - assert(landlock_abi <= LANDLOCK_ABI_MAX); - - if (landlock_abi <= 0) + // Initialize the ruleset to forbid all actions that the available + // Landlock ABI version supports. Return if Landlock isn't supported + // at all. + struct landlock_ruleset_attr attr; + if (my_landlock_ruleset_attr_forbid_all(&attr) == -1) return; - // We want to set all supported flags in handled_access_fs. - // This way the ruleset will initially forbid access to all - // actions that the available Landlock ABI version supports. - // Exceptions can be added using landlock_add_rule(2) to - // allow certain actions on certain files or directories. - // - // The same flag values are used on all archs. ABI v2 and v3 - // both add one new flag. - // - // First in ABI v1: LANDLOCK_ACCESS_FS_EXECUTE = 1ULL << 0 - // Last in ABI v1: LANDLOCK_ACCESS_FS_MAKE_SYM = 1ULL << 12 - // Last in ABI v2: LANDLOCK_ACCESS_FS_REFER = 1ULL << 13 - // Last in ABI v3: LANDLOCK_ACCESS_FS_TRUNCATE = 1ULL << 14 - // - // This makes it simple to set the mask based on the ABI - // version and we don't need to care which flags are #defined - // in the installed for ABI versions 1-3. - const struct landlock_ruleset_attr attr = { - .handled_access_fs = ~required_rights - & ((1ULL << (12 + my_min(3, landlock_abi))) - 1), -#if LANDLOCK_ABI_MAX >= 4 - .handled_access_net = landlock_abi < 4 ? 0 : - (LANDLOCK_ACCESS_NET_BIND_TCP - | LANDLOCK_ACCESS_NET_CONNECT_TCP), -#endif - }; + // Allow the required rights. + attr.handled_access_fs &= ~required_rights; - const int ruleset_fd = syscall(SYS_landlock_create_ruleset, - &attr, sizeof(attr), 0U); + // Create the ruleset in the kernel. This shouldn't fail. + const int ruleset_fd = my_landlock_create_ruleset( + &attr, sizeof(attr), 0); if (ruleset_fd < 0) message_fatal(_("Failed to enable the sandbox")); @@ -193,7 +153,7 @@ enable_landlock(uint64_t required_rights) // // prctl(PR_SET_NO_NEW_PRIVS, ...) was already called in // sandbox_init() so we don't do it here again. - if (syscall(SYS_landlock_restrict_self, ruleset_fd, 0U) != 0) + if (my_landlock_restrict_self(ruleset_fd, 0) != 0) message_fatal(_("Failed to enable the sandbox")); (void)close(ruleset_fd); @@ -214,14 +174,6 @@ sandbox_init(void) // fails here the error will still be detected when it matters. (void)prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); - // Get the highest Landlock ABI version supported by the kernel. - landlock_abi = syscall(SYS_landlock_create_ruleset, - (void *)NULL, 0, LANDLOCK_CREATE_RULESET_VERSION); - - // The kernel might support a newer ABI than this file. - if (landlock_abi > LANDLOCK_ABI_MAX) - landlock_abi = LANDLOCK_ABI_MAX; - // These are all in ABI version 1 already. We don't need truncate // rights because files are created with open() using O_EXCL and // without O_TRUNC.