Revert "Merge branch 'seccomp' of https://github.com/aszlig/nix"

This reverts commit 9f3f2e21ed, reversing
changes made to 47f587700d.
This commit is contained in:
Eelco Dolstra 2016-12-19 11:52:57 +01:00
parent 11f0680f69
commit 3a4bd320c2
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
6 changed files with 30 additions and 139 deletions

View file

@ -10,7 +10,6 @@ OPENSSL_LIBS = @OPENSSL_LIBS@
PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@ PACKAGE_VERSION = @PACKAGE_VERSION@
SODIUM_LIBS = @SODIUM_LIBS@ SODIUM_LIBS = @SODIUM_LIBS@
LIBSECCOMP_LIBS = @LIBSECCOMP_LIBS@
LIBLZMA_LIBS = @LIBLZMA_LIBS@ LIBLZMA_LIBS = @LIBLZMA_LIBS@
SQLITE3_LIBS = @SQLITE3_LIBS@ SQLITE3_LIBS = @SQLITE3_LIBS@
bash = @bash@ bash = @bash@

View file

@ -193,15 +193,6 @@ AC_SUBST(HAVE_SODIUM, [$have_sodium])
PKG_CHECK_MODULES([LIBLZMA], [liblzma], [CXXFLAGS="$LIBLZMA_CFLAGS $CXXFLAGS"]) 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. # Look for aws-cpp-sdk-s3.
AC_LANG_PUSH(C++) AC_LANG_PUSH(C++)
AC_CHECK_HEADERS([aws/s3/S3Client.h], AC_CHECK_HEADERS([aws/s3/S3Client.h],

View file

@ -25,7 +25,7 @@ let
buildInputs = buildInputs =
[ curl bison flex perl libxml2 libxslt bzip2 xz [ curl bison flex perl libxml2 libxslt bzip2 xz
pkgconfig sqlite libsodium libseccomp boehmgc pkgconfig sqlite libsodium boehmgc
docbook5 docbook5_xsl docbook5 docbook5_xsl
autoconf-archive autoconf-archive
] ++ lib.optional (!lib.inNixShell) git; ] ++ lib.optional (!lib.inNixShell) git;
@ -74,7 +74,6 @@ let
buildInputs = buildInputs =
[ curl perl bzip2 xz openssl pkgconfig sqlite boehmgc ] [ curl perl bzip2 xz openssl pkgconfig sqlite boehmgc ]
++ lib.optional stdenv.isLinux libsodium ++ lib.optional stdenv.isLinux libsodium
++ lib.optional stdenv.isLinux libseccomp
++ lib.optional stdenv.isLinux ++ lib.optional stdenv.isLinux
(aws-sdk-cpp.override { (aws-sdk-cpp.override {
apis = ["s3"]; apis = ["s3"];
@ -197,10 +196,6 @@ let
nix = build.x86_64-linux; system = "x86_64-linux"; 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 = tests.binaryTarball =
with import <nixpkgs> { system = "x86_64-linux"; }; with import <nixpkgs> { system = "x86_64-linux"; };
vmTools.runInLinuxImage (runCommand "nix-binary-tarball-test" vmTools.runInLinuxImage (runCommand "nix-binary-tarball-test"

View file

@ -54,7 +54,6 @@
#include <sys/param.h> #include <sys/param.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <seccomp.h>
#define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root, put_old)) #define pivot_root(new_root, put_old) (syscall(SYS_pivot_root, new_root, put_old))
#endif #endif
@ -815,6 +814,9 @@ private:
result. */ result. */
ValidPathInfos prevInfos; ValidPathInfos prevInfos;
const uid_t sandboxUid = 1000;
const gid_t sandboxGid = 100;
public: public:
DerivationGoal(const Path & drvPath, const StringSet & wantedOutputs, DerivationGoal(const Path & drvPath, const StringSet & wantedOutputs,
Worker & worker, BuildMode buildMode = bmNormal); 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) int childEntry(void * arg)
{ {
setupSeccomp();
((DerivationGoal *) arg)->runChild(); ((DerivationGoal *) arg)->runChild();
return 1; return 1;
} }
@ -2011,14 +1965,18 @@ void DerivationGoal::startBuilder()
createDirs(chrootRootDir + "/etc"); createDirs(chrootRootDir + "/etc");
writeFile(chrootRootDir + "/etc/passwd", writeFile(chrootRootDir + "/etc/passwd",
"root:x:0:0:Nix build user:/:/noshell\n" (format(
"nobody:x:65534:65534:Nobody:/:/noshell\n"); "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 /* Declare the build user's group so that programs get a consistent
view of the system (e.g., "id -gn"). */ view of the system (e.g., "id -gn"). */
writeFile(chrootRootDir + "/etc/group", writeFile(chrootRootDir + "/etc/group",
"root:x:0:\n" (format(
"nobody:x:65534:\n"); "root:x:0:\n"
"nixbld:!:%1%:\n"
"nogroup:x:65534:\n") % sandboxGid).str());
/* Create /etc/hosts with localhost entry. */ /* Create /etc/hosts with localhost entry. */
if (!fixedOutput) if (!fixedOutput)
@ -2202,7 +2160,12 @@ void DerivationGoal::startBuilder()
Pid helper = startProcess([&]() { Pid helper = startProcess([&]() {
/* Drop additional groups here because we can't do it /* 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) if (getuid() == 0 && setgroups(0, 0) == -1)
throw SysError("setgroups failed"); throw SysError("setgroups failed");
@ -2235,19 +2198,19 @@ void DerivationGoal::startBuilder()
if (!string2Int<pid_t>(readLine(builderOut.readSide.get()), tmp)) abort(); if (!string2Int<pid_t>(readLine(builderOut.readSide.get()), tmp)) abort();
pid = tmp; pid = tmp;
/* Set the UID/GID mapping of the builder's user /* Set the UID/GID mapping of the builder's user namespace
namespace such that root maps to the build user, or to the such that the sandbox user maps to the build user, or to
calling user (if build users are disabled). */ the calling user (if build users are disabled). */
uid_t targetUid = buildUser.enabled() ? buildUser.getUID() : getuid(); uid_t hostUid = buildUser.enabled() ? buildUser.getUID() : getuid();
uid_t targetGid = buildUser.enabled() ? buildUser.getGID() : getgid(); uid_t hostGid = buildUser.enabled() ? buildUser.getGID() : getgid();
writeFile("/proc/" + std::to_string(pid) + "/uid_map", 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) + "/setgroups", "deny");
writeFile("/proc/" + std::to_string(pid) + "/gid_map", 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 /* Signal the builder that we've updated its user
namespace. */ namespace. */
@ -2457,11 +2420,12 @@ void DerivationGoal::runChild()
if (rmdir("real-root") == -1) if (rmdir("real-root") == -1)
throw SysError("cannot remove real-root directory"); throw SysError("cannot remove real-root directory");
/* Become root in the user namespace, which corresponds to /* Switch to the sandbox uid/gid in the user namespace,
the build user or calling user in the parent namespace. */ which corresponds to the build user or calling user in
if (setgid(0) == -1) the parent namespace. */
if (setgid(sandboxGid) == -1)
throw SysError("setgid failed"); throw SysError("setgid failed");
if (setuid(0) == -1) if (setuid(sandboxUid) == -1)
throw SysError("setuid failed"); throw SysError("setuid failed");
setUser = false; setUser = false;

View file

@ -18,10 +18,6 @@ ifeq ($(OS), SunOS)
libstore_LDFLAGS += -lsocket libstore_LDFLAGS += -lsocket
endif endif
ifeq ($(OS), Linux)
libstore_LDFLAGS += -lseccomp
endif
libstore_CXXFLAGS = \ libstore_CXXFLAGS = \
-DNIX_PREFIX=\"$(prefix)\" \ -DNIX_PREFIX=\"$(prefix)\" \
-DNIX_STORE_DIR=\"$(storedir)\" \ -DNIX_STORE_DIR=\"$(storedir)\" \

View file

@ -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"}");
'';
}