From 328c52da8a2bbb81307644efdb58db2c422d9ba7 Mon Sep 17 00:00:00 2001 From: Jia Tan Date: Mon, 26 Feb 2024 23:02:06 +0800 Subject: [PATCH] Build: Fix Linux Landlock feature test in Autotools and CMake builds. The previous Linux Landlock feature test assumed that having the linux/landlock.h header file was enough. The new feature tests also requires that prctl() and the required Landlock system calls are supported. --- CMakeLists.txt | 25 ++++++++++++++++++++++--- configure.ac | 27 ++++++++++++++++++++++++++- src/xz/sandbox.c | 2 +- src/xz/sandbox.h | 2 +- src/xzdec/xzdec.c | 8 ++++---- 5 files changed, 54 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 76700591..d2b1af7a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -901,10 +901,29 @@ endif() # Sandboxing: Landlock if(NOT SANDBOX_FOUND AND ENABLE_SANDBOX MATCHES "^ON$|^landlock$") - check_include_file(linux/landlock.h HAVE_LINUX_LANDLOCK_H) + # A compile check is done here because some systems have + # linux/landlock.h, but do not have the syscalls defined + # in order to actually use Linux Landlock. + check_c_source_compiles(" + #include + #include + #include +. + void my_sandbox(void) + { + (void)prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + (void)SYS_landlock_create_ruleset; + (void)SYS_landlock_restrict_self; + (void)LANDLOCK_CREATE_RULESET_VERSION; + return; + } - if(HAVE_LINUX_LANDLOCK_H) - set(SANDBOX_COMPILE_DEFINITION "HAVE_LINUX_LANDLOCK_H") + int main(void) { return 0; } + " + HAVE_LINUX_LANDLOCK) + + if(HAVE_LINUX_LANDLOCK) + set(SANDBOX_COMPILE_DEFINITION "HAVE_LINUX_LANDLOCK") set(SANDBOX_FOUND ON) # Of our three sandbox methods, only Landlock is incompatible diff --git a/configure.ac b/configure.ac index 3676cd03..446e26e2 100644 --- a/configure.ac +++ b/configure.ac @@ -1177,12 +1177,37 @@ AS_CASE([$enable_sandbox], ) AS_CASE([$enable_sandbox], [auto | landlock], [ - AC_CHECK_HEADERS([linux/landlock.h], [ + AC_MSG_CHECKING([if Linux Landlock is usable]) + + # A compile check is done here because some systems have + # linux/landlock.h, but do not have the syscalls defined + # in order to actually use Linux Landlock. + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + + void my_sandbox(void) + { + (void)prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + (void)SYS_landlock_create_ruleset; + (void)SYS_landlock_restrict_self; + (void)LANDLOCK_CREATE_RULESET_VERSION; + return; + } + ]])], [ enable_sandbox=found AS_CASE([$CFLAGS], [*-fsanitize=*], [AC_MSG_ERROR([ CFLAGS contains '-fsanitize=' which is incompatible with the Landlock sandboxing. Use --disable-sandbox when using '-fsanitize'.])]) + + AC_DEFINE([HAVE_LINUX_LANDLOCK], [1], + [Define to 1 if Linux Landlock is supported. + See configure.ac for details.]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) ]) ] ) diff --git a/src/xz/sandbox.c b/src/xz/sandbox.c index 3b3069c8..5bd22737 100644 --- a/src/xz/sandbox.c +++ b/src/xz/sandbox.c @@ -109,7 +109,7 @@ sandbox_enable_strict_if_allowed(int src_fd lzma_attribute((__unused__)), } -#elif defined(HAVE_LINUX_LANDLOCK_H) +#elif defined(HAVE_LINUX_LANDLOCK) ////////////// // Landlock // diff --git a/src/xz/sandbox.h b/src/xz/sandbox.h index f41b4725..98b9862a 100644 --- a/src/xz/sandbox.h +++ b/src/xz/sandbox.h @@ -9,7 +9,7 @@ // /////////////////////////////////////////////////////////////////////////////// -#if defined(HAVE_PLEDGE) || defined(HAVE_LINUX_LANDLOCK_H) \ +#if defined(HAVE_PLEDGE) || defined(HAVE_LINUX_LANDLOCK) \ || defined(HAVE_CAP_RIGHTS_LIMIT) # define ENABLE_SANDBOX 1 #endif diff --git a/src/xzdec/xzdec.c b/src/xzdec/xzdec.c index 6fd0be39..ef8c80f3 100644 --- a/src/xzdec/xzdec.c +++ b/src/xzdec/xzdec.c @@ -24,14 +24,14 @@ # include #endif -#ifdef HAVE_LINUX_LANDLOCK_H +#ifdef HAVE_LINUX_LANDLOCK # include # include # include #endif #if defined(HAVE_CAP_RIGHTS_LIMIT) || defined(HAVE_PLEDGE) \ - || defined(HAVE_LINUX_LANDLOCK_H) + || defined(HAVE_LINUX_LANDLOCK) # define ENABLE_SANDBOX 1 #endif @@ -325,7 +325,7 @@ sandbox_enter(int src_fd) goto error; (void)src_fd; -#elif defined(HAVE_LINUX_LANDLOCK_H) +#elif defined(HAVE_LINUX_LANDLOCK) int landlock_abi = syscall(SYS_landlock_create_ruleset, (void *)NULL, 0, LANDLOCK_CREATE_RULESET_VERSION); @@ -389,7 +389,7 @@ main(int argc, char **argv) } #endif -#ifdef HAVE_LINUX_LANDLOCK_H +#ifdef HAVE_LINUX_LANDLOCK // Prevent the process from gaining new privileges. The return // is ignored to keep compatibility with old kernels. (void)prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);