Merge commit '6aa64627c8e431c3b187f7bb44c943d06e39b929' into auto-uid-allocation

This commit is contained in:
John Ericson 2020-10-17 19:12:59 +00:00
commit 81c5f754a7

View file

@ -720,6 +720,10 @@ private:
paths to the sandbox as a result of recursive Nix calls. */ paths to the sandbox as a result of recursive Nix calls. */
AutoCloseFD sandboxMountNamespace; AutoCloseFD sandboxMountNamespace;
/* On Linux, whether we're doing the build in its own user
namespace. */
bool usingUserNamespace = true;
/* The build hook. */ /* The build hook. */
std::unique_ptr<HookInstance> hook; std::unique_ptr<HookInstance> hook;
@ -2319,8 +2323,8 @@ void DerivationGoal::startBuilder()
if (useUidRange && (!buildUser || buildUser->getUIDCount() < 65536)) if (useUidRange && (!buildUser || buildUser->getUIDCount() < 65536))
throw Error("feature 'uid-range' requires '%s' to be enabled", settings.autoAllocateUids.name); throw Error("feature 'uid-range' requires '%s' to be enabled", settings.autoAllocateUids.name);
sandboxUid = useUidRange ? 0 : 1000; sandboxUid = useUidRange && usingUserNamespace ? 0 : 1000;
sandboxGid = useUidRange ? 0 : 100; sandboxGid = useUidRange && usingUserNamespace ? 0 : 100;
writeFile(chrootRootDir + "/etc/passwd", fmt( writeFile(chrootRootDir + "/etc/passwd", fmt(
"root:x:0:0:Nix build user:%3%:/noshell\n" "root:x:0:0:Nix build user:%3%:/noshell\n"
@ -2551,6 +2555,24 @@ void DerivationGoal::startBuilder()
options.allowVfork = false; options.allowVfork = false;
Path maxUserNamespaces = "/proc/sys/user/max_user_namespaces";
static bool userNamespacesEnabled =
pathExists(maxUserNamespaces)
&& trim(readFile(maxUserNamespaces)) != "0";
usingUserNamespace = userNamespacesEnabled;
if (usingUserNamespace) {
sandboxUid = 1000;
sandboxGid = 100;
} else {
debug("note: not using a user namespace");
if (!buildUser)
throw Error("cannot perform a sandboxed build because user namespaces are not enabled; check /proc/sys/user/max_user_namespaces");
sandboxUid = buildUser->getUID();
sandboxGid = buildUser->getGID();
}
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
@ -2569,9 +2591,11 @@ void DerivationGoal::startBuilder()
PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
if (stack == MAP_FAILED) throw SysError("allocating stack"); if (stack == MAP_FAILED) throw SysError("allocating stack");
int flags = CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWUTS | CLONE_PARENT | SIGCHLD; int flags = CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWUTS | CLONE_PARENT | SIGCHLD;
if (privateNetwork) if (privateNetwork)
flags |= CLONE_NEWNET; flags |= CLONE_NEWNET;
if (usingUserNamespace)
flags |= CLONE_NEWUSER;
pid_t child = clone(childEntry, stack + stackSize, flags, this); pid_t child = clone(childEntry, stack + stackSize, flags, this);
if (child == -1 && errno == EINVAL) { if (child == -1 && errno == EINVAL) {
@ -2619,6 +2643,7 @@ 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;
if (usingUserNamespace) {
/* Set the UID/GID mapping of the builder's user namespace /* Set the UID/GID mapping of the builder's user namespace
such that the sandbox user maps to the build user, or to such that the sandbox user maps to the build user, or to
the calling user (if build users are disabled). */ the calling user (if build users are disabled). */
@ -2634,6 +2659,7 @@ void DerivationGoal::startBuilder()
writeFile("/proc/" + std::to_string(pid) + "/gid_map", writeFile("/proc/" + std::to_string(pid) + "/gid_map",
fmt("%d %d %d", sandboxGid, hostGid, nrIds)); fmt("%d %d %d", sandboxGid, hostGid, nrIds));
}
/* Save the mount namespace of the child. We have to do this /* Save the mount namespace of the child. We have to do this
*before* the child does a chroot. */ *before* the child does a chroot. */
@ -2675,7 +2701,7 @@ void DerivationGoal::startBuilder()
ex.addTrace({}, "while setting up the build environment"); ex.addTrace({}, "while setting up the build environment");
throw ex; throw ex;
} }
debug(msg); debug("sandbox setup: " + msg);
} }
} }