forked from lix-project/lix
Revert "Merge branch 'seccomp' of https://github.com/aszlig/nix"
This reverts commit9f3f2e21ed
, reversing changes made to47f587700d
.
This commit is contained in:
parent
11f0680f69
commit
3a4bd320c2
|
@ -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@
|
||||||
|
|
|
@ -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],
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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",
|
||||||
|
(format(
|
||||||
"root:x:0:0:Nix build user:/:/noshell\n"
|
"root:x:0:0:Nix build user:/:/noshell\n"
|
||||||
"nobody:x:65534:65534:Nobody:/:/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",
|
||||||
|
(format(
|
||||||
"root:x:0:\n"
|
"root:x:0:\n"
|
||||||
"nobody:x:65534:\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;
|
||||||
|
|
|
@ -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)\" \
|
||||||
|
|
|
@ -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"}");
|
|
||||||
'';
|
|
||||||
}
|
|
Loading…
Reference in a new issue