aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.config.in1
-rw-r--r--configure.ac9
-rw-r--r--release.nix7
-rw-r--r--src/libstore/build.cc94
-rw-r--r--src/libstore/local.mk4
-rw-r--r--tests/sandbox.nix54
6 files changed, 30 insertions, 139 deletions
diff --git a/Makefile.config.in b/Makefile.config.in
index 08408ea5f..a03776d57 100644
--- a/Makefile.config.in
+++ b/Makefile.config.in
@@ -10,7 +10,6 @@ OPENSSL_LIBS = @OPENSSL_LIBS@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
SODIUM_LIBS = @SODIUM_LIBS@
-LIBSECCOMP_LIBS = @LIBSECCOMP_LIBS@
LIBLZMA_LIBS = @LIBLZMA_LIBS@
SQLITE3_LIBS = @SQLITE3_LIBS@
bash = @bash@
diff --git a/configure.ac b/configure.ac
index 4e1806270..e6b11be2d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -193,15 +193,6 @@ AC_SUBST(HAVE_SODIUM, [$have_sodium])
PKG_CHECK_MODULES([LIBLZMA], [liblzma], [CXXFLAGS="$LIBLZMA_CFLAGS $CXXFLAGS"])
-# Look for libseccomp, required for Linux sandboxing.
-if test "$sys_name" = linux; then
- PKG_CHECK_MODULES([LIBSECCOMP], [libseccomp],
- [CXXFLAGS="$LIBSECCOMP_CFLAGS $CXXFLAGS"])
-# AC_CHECK_LIB([seccomp], [seccomp_init], [true],
-# [AC_MSG_ERROR([Nix requires libseccomp for sandboxing. See https://github.com/seccomp/libseccomp.])])
-fi
-
-
# Look for aws-cpp-sdk-s3.
AC_LANG_PUSH(C++)
AC_CHECK_HEADERS([aws/s3/S3Client.h],
diff --git a/release.nix b/release.nix
index 7c5e6125b..d825dd583 100644
--- a/release.nix
+++ b/release.nix
@@ -25,7 +25,7 @@ let
buildInputs =
[ curl bison flex perl libxml2 libxslt bzip2 xz
- pkgconfig sqlite libsodium libseccomp boehmgc
+ pkgconfig sqlite libsodium boehmgc
docbook5 docbook5_xsl
autoconf-archive
] ++ lib.optional (!lib.inNixShell) git;
@@ -74,7 +74,6 @@ let
buildInputs =
[ curl perl bzip2 xz openssl pkgconfig sqlite boehmgc ]
++ lib.optional stdenv.isLinux libsodium
- ++ lib.optional stdenv.isLinux libseccomp
++ lib.optional stdenv.isLinux
(aws-sdk-cpp.override {
apis = ["s3"];
@@ -197,10 +196,6 @@ let
nix = build.x86_64-linux; system = "x86_64-linux";
});
- tests.sandbox = (import ./tests/sandbox.nix rec {
- nix = build.x86_64-linux; system = "x86_64-linux";
- });
-
tests.binaryTarball =
with import <nixpkgs> { system = "x86_64-linux"; };
vmTools.runInLinuxImage (runCommand "nix-binary-tarball-test"
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index f702433a0..c970fbdca 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -54,7 +54,6 @@
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/syscall.h>
-#include <seccomp.h>
#define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root, put_old))
#endif
@@ -815,6 +814,9 @@ private:
result. */
ValidPathInfos prevInfos;
+ const uid_t sandboxUid = 1000;
+ const gid_t sandboxGid = 100;
+
public:
DerivationGoal(const Path & drvPath, const StringSet & wantedOutputs,
Worker & worker, BuildMode buildMode = bmNormal);
@@ -1642,56 +1644,8 @@ void chmod_(const Path & path, mode_t mode)
}
-#if __linux__
-
-#define FORCE_SUCCESS(syscall) \
- if (seccomp_rule_add(ctx, SCMP_ACT_ERRNO(0), SCMP_SYS(syscall), 0) != 0) { \
- seccomp_release(ctx); \
- throw SysError("unable to add seccomp rule for " #syscall); \
- }
-
-void setupSeccomp(void) {
- scmp_filter_ctx ctx;
-
- if ((ctx = seccomp_init(SCMP_ACT_ALLOW)) == NULL)
- throw SysError("unable to initialize seccomp mode 2");
-
-#if defined(__x86_64__)
- if (seccomp_arch_add(ctx, SCMP_ARCH_X86) != 0) {
- seccomp_release(ctx);
- throw SysError("unable to add 32bit seccomp architecture");
- }
-#endif
-
- FORCE_SUCCESS(chown32);
- FORCE_SUCCESS(fchown32);
- FORCE_SUCCESS(lchown32);
-
- FORCE_SUCCESS(chown);
- FORCE_SUCCESS(fchown);
- FORCE_SUCCESS(fchownat);
- FORCE_SUCCESS(lchown);
-
- FORCE_SUCCESS(setxattr);
- FORCE_SUCCESS(lsetxattr);
- FORCE_SUCCESS(fsetxattr);
-
- if (seccomp_load(ctx) != 0) {
- seccomp_release(ctx);
- throw SysError("unable to load seccomp BPF program");
- }
-
- seccomp_release(ctx);
-}
-
-#undef FORCE_SUCCESS
-
-#endif
-
-
int childEntry(void * arg)
{
- setupSeccomp();
((DerivationGoal *) arg)->runChild();
return 1;
}
@@ -2011,14 +1965,18 @@ void DerivationGoal::startBuilder()
createDirs(chrootRootDir + "/etc");
writeFile(chrootRootDir + "/etc/passwd",
- "root:x:0:0:Nix build user:/:/noshell\n"
- "nobody:x:65534:65534:Nobody:/:/noshell\n");
+ (format(
+ "root:x:0:0:Nix build user:/:/noshell\n"
+ "nixbld:x:%1%:%2%:Nix build user:/:/noshell\n"
+ "nobody:x:65534:65534:Nobody:/:/noshell\n") % sandboxUid % sandboxGid).str());
/* Declare the build user's group so that programs get a consistent
view of the system (e.g., "id -gn"). */
writeFile(chrootRootDir + "/etc/group",
- "root:x:0:\n"
- "nobody:x:65534:\n");
+ (format(
+ "root:x:0:\n"
+ "nixbld:!:%1%:\n"
+ "nogroup:x:65534:\n") % sandboxGid).str());
/* Create /etc/hosts with localhost entry. */
if (!fixedOutput)
@@ -2202,7 +2160,12 @@ void DerivationGoal::startBuilder()
Pid helper = startProcess([&]() {
/* Drop additional groups here because we can't do it
- after we've created the new user namespace. */
+ after we've created the new user namespace. FIXME:
+ this means that if we're not root in the parent
+ namespace, we can't drop additional groups; they will
+ be mapped to nogroup in the child namespace. There does
+ not seem to be a workaround for this. (But who can tell
+ from reading user_namespaces(7)?)*/
if (getuid() == 0 && setgroups(0, 0) == -1)
throw SysError("setgroups failed");
@@ -2235,19 +2198,19 @@ void DerivationGoal::startBuilder()
if (!string2Int<pid_t>(readLine(builderOut.readSide.get()), tmp)) abort();
pid = tmp;
- /* Set the UID/GID mapping of the builder's user
- namespace such that root maps to the build user, or to the
- calling user (if build users are disabled). */
- uid_t targetUid = buildUser.enabled() ? buildUser.getUID() : getuid();
- uid_t targetGid = buildUser.enabled() ? buildUser.getGID() : getgid();
+ /* Set the UID/GID mapping of the builder's user namespace
+ such that the sandbox user maps to the build user, or to
+ the calling user (if build users are disabled). */
+ uid_t hostUid = buildUser.enabled() ? buildUser.getUID() : getuid();
+ uid_t hostGid = buildUser.enabled() ? buildUser.getGID() : getgid();
writeFile("/proc/" + std::to_string(pid) + "/uid_map",
- (format("0 %d 1") % targetUid).str());
+ (format("%d %d 1") % sandboxUid % hostUid).str());
writeFile("/proc/" + std::to_string(pid) + "/setgroups", "deny");
writeFile("/proc/" + std::to_string(pid) + "/gid_map",
- (format("0 %d 1") % targetGid).str());
+ (format("%d %d 1") % sandboxGid % hostGid).str());
/* Signal the builder that we've updated its user
namespace. */
@@ -2457,11 +2420,12 @@ void DerivationGoal::runChild()
if (rmdir("real-root") == -1)
throw SysError("cannot remove real-root directory");
- /* Become root in the user namespace, which corresponds to
- the build user or calling user in the parent namespace. */
- if (setgid(0) == -1)
+ /* Switch to the sandbox uid/gid in the user namespace,
+ which corresponds to the build user or calling user in
+ the parent namespace. */
+ if (setgid(sandboxGid) == -1)
throw SysError("setgid failed");
- if (setuid(0) == -1)
+ if (setuid(sandboxUid) == -1)
throw SysError("setuid failed");
setUser = false;
diff --git a/src/libstore/local.mk b/src/libstore/local.mk
index a8222025c..9d5c04dca 100644
--- a/src/libstore/local.mk
+++ b/src/libstore/local.mk
@@ -18,10 +18,6 @@ ifeq ($(OS), SunOS)
libstore_LDFLAGS += -lsocket
endif
-ifeq ($(OS), Linux)
- libstore_LDFLAGS += -lseccomp
-endif
-
libstore_CXXFLAGS = \
-DNIX_PREFIX=\"$(prefix)\" \
-DNIX_STORE_DIR=\"$(storedir)\" \
diff --git a/tests/sandbox.nix b/tests/sandbox.nix
deleted file mode 100644
index dc72a5985..000000000
--- a/tests/sandbox.nix
+++ /dev/null
@@ -1,54 +0,0 @@
-# Test Nix builder sandbox.
-
-{ system, nix }:
-
-with import <nixpkgs/nixos/lib/testing.nix> { inherit system; };
-
-let
- mkUtils = pkgs: pkgs.buildEnv {
- name = "sandbox-utils";
- paths = [ pkgs.coreutils pkgs.utillinux pkgs.bash ];
- pathsToLink = [ "/bin" "/sbin" ];
- };
-
- utils32 = mkUtils pkgs.pkgsi686Linux;
- utils64 = mkUtils pkgs;
-
- sandboxTestScript = pkgs.writeText "sandbox-testscript.sh" ''
- [ $(id -u) -eq 0 ]
- cp -p "$testfile" foo
- chown 1024:1024 foo
- touch "$out"
- '';
-
- testExpr = arch: pkgs.writeText "sandbox-test.nix" ''
- let
- utils = builtins.storePath
- ${if arch == "i686-linux" then utils32 else utils64};
- in derivation {
- name = "sandbox-test";
- system = "${arch}";
- builder = "''${utils}/bin/bash";
- args = ["-e" ${sandboxTestScript}];
- PATH = "''${utils}/bin";
- testfile = builtins.toFile "test" "i am a test file";
- }
- '';
-
-in makeTest {
- name = "nix-sandbox";
-
- machine = { pkgs, ... }: {
- nix.package = nix;
- nix.useSandbox = true;
- nix.binaryCaches = [];
- virtualisation.writableStore = true;
- virtualisation.pathsInNixDB = [ utils32 utils64 ];
- };
-
- testScript = ''
- $machine->waitForUnit("multi-user.target");
- $machine->succeed("nix-build ${testExpr "x86_64-linux"}");
- $machine->succeed("nix-build ${testExpr "i686-linux"}");
- '';
-}