aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
authorMaximilian Bosch <maximilian@mbosch.me>2024-05-04 07:26:15 +0000
committerGerrit Code Review <gerrit@lix>2024-05-04 07:26:15 +0000
commit79d0ae667066b758fd4202cd18294a0f40ddc8f0 (patch)
tree675df833182fbf4909a8a99a5d18c12ebad317da /src/libstore
parentf8617f9dc65096ee1e83fe3d100cc252e9f94bf6 (diff)
parent045ee374387cb8fd9b1d83b14574c6d92694063d (diff)
Merge "libstore/local-derivation-goal: prohibit creating setuid/setgid binaries" into main
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build/local-derivation-goal.cc5
-rw-r--r--src/libstore/linux/fchmodat2-compat.hh37
2 files changed, 42 insertions, 0 deletions
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
index 03e33a46d..4278fab85 100644
--- a/src/libstore/build/local-derivation-goal.cc
+++ b/src/libstore/build/local-derivation-goal.cc
@@ -35,6 +35,7 @@
/* Includes required for chroot support. */
#if __linux__
#include <sys/ioctl.h>
+#include "linux/fchmodat2-compat.hh"
#include <net/if.h>
#include <netinet/ip.h>
#include <sys/mman.h>
@@ -1664,6 +1665,10 @@ void setupSeccomp()
if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fchmodat), 1,
SCMP_A2(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm)) != 0)
throw SysError("unable to add seccomp rule");
+
+ if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), NIX_SYSCALL_FCHMODAT2, 1,
+ SCMP_A2(SCMP_CMP_MASKED_EQ, (scmp_datum_t) perm, (scmp_datum_t) perm)) != 0)
+ throw SysError("unable to add seccomp rule");
}
/* Prevent builders from creating EAs or ACLs. Not all filesystems
diff --git a/src/libstore/linux/fchmodat2-compat.hh b/src/libstore/linux/fchmodat2-compat.hh
new file mode 100644
index 000000000..b05da6786
--- /dev/null
+++ b/src/libstore/linux/fchmodat2-compat.hh
@@ -0,0 +1,37 @@
+/*
+ * Determine the syscall number for `fchmodat2`.
+ *
+ * On most platforms this is 452. Exceptions can be found on
+ * a glibc git checkout via `rg --pcre2 'define __NR_fchmodat2 (?!452)'`.
+ *
+ * The problem is that glibc 2.39 and libseccomp 2.5.5 are needed to
+ * get the syscall number. However, a Nix built against nixpkgs 23.11
+ * (glibc 2.38) should still have the issue fixed without depending
+ * on the build environment.
+ *
+ * To achieve that, the macros below try to determine the platform and
+ * set the syscall number which is platform-specific, but
+ * in most cases 452.
+ *
+ * TODO: remove this when 23.11 is EOL and the entire (supported) ecosystem
+ * is on glibc 2.39.
+ */
+
+#pragma once
+///@file
+
+#if HAVE_SECCOMP
+# if defined(__alpha__)
+# define NIX_SYSCALL_FCHMODAT2 562
+# elif defined(__x86_64__) && SIZE_MAX == 0xFFFFFFFF // x32
+# define NIX_SYSCALL_FCHMODAT2 1073742276
+# elif defined(__mips__) && defined(__mips64) && defined(_ABIN64) // mips64/n64
+# define NIX_SYSCALL_FCHMODAT2 5452
+# elif defined(__mips__) && defined(__mips64) && defined(_ABIN32) // mips64/n32
+# define NIX_SYSCALL_FCHMODAT2 6452
+# elif defined(__mips__) && defined(_ABIO32) // mips32
+# define NIX_SYSCALL_FCHMODAT2 4452
+# else
+# define NIX_SYSCALL_FCHMODAT2 452
+# endif
+#endif // HAVE_SECCOMP