Merge branch 'recursive-nix-fix' of https://github.com/L-as/nix

This commit is contained in:
Eelco Dolstra 2022-01-10 16:51:59 +01:00
commit df11e75d0e
2 changed files with 11 additions and 3 deletions

View file

@ -260,6 +260,7 @@ void LocalDerivationGoal::cleanupHookFinally()
void LocalDerivationGoal::cleanupPreChildKill() void LocalDerivationGoal::cleanupPreChildKill()
{ {
sandboxMountNamespace = -1; sandboxMountNamespace = -1;
sandboxUserNamespace = -1;
} }
@ -906,11 +907,14 @@ void LocalDerivationGoal::startBuilder()
"nobody:x:65534:65534:Nobody:/:/noshell\n", "nobody:x:65534:65534:Nobody:/:/noshell\n",
sandboxUid(), sandboxGid(), settings.sandboxBuildDir)); sandboxUid(), sandboxGid(), settings.sandboxBuildDir));
/* Save the mount namespace of the child. We have to do this /* Save the mount- and user namespace of the child. We have to do this
*before* the child does a chroot. */ *before* the child does a chroot. */
sandboxMountNamespace = open(fmt("/proc/%d/ns/mnt", (pid_t) pid).c_str(), O_RDONLY); sandboxMountNamespace = open(fmt("/proc/%d/ns/mnt", (pid_t) pid).c_str(), O_RDONLY);
if (sandboxMountNamespace.get() == -1) if (sandboxMountNamespace.get() == -1)
throw SysError("getting sandbox mount namespace"); throw SysError("getting sandbox mount namespace");
sandboxUserNamespace = open(fmt("/proc/%d/ns/user", (pid_t) pid).c_str(), O_RDONLY);
if (sandboxUserNamespace.get() == -1)
throw SysError("getting sandbox user namespace");
/* Signal the builder that we've updated its user namespace. */ /* Signal the builder that we've updated its user namespace. */
writeFull(userNamespaceSync.writeSide.get(), "1"); writeFull(userNamespaceSync.writeSide.get(), "1");
@ -1423,7 +1427,7 @@ void LocalDerivationGoal::addDependency(const StorePath & path)
Path source = worker.store.Store::toRealPath(path); Path source = worker.store.Store::toRealPath(path);
Path target = chrootRootDir + worker.store.printStorePath(path); Path target = chrootRootDir + worker.store.printStorePath(path);
debug("bind-mounting %s -> %s", target, source); debug("bind-mounting %s -> %s", source, target);
if (pathExists(target)) if (pathExists(target))
throw Error("store path '%s' already exists in the sandbox", worker.store.printStorePath(path)); throw Error("store path '%s' already exists in the sandbox", worker.store.printStorePath(path));
@ -1438,6 +1442,9 @@ void LocalDerivationGoal::addDependency(const StorePath & path)
child process.*/ child process.*/
Pid child(startProcess([&]() { Pid child(startProcess([&]() {
if (usingUserNamespace && (setns(sandboxUserNamespace.get(), 0) == -1))
throw SysError("entering sandbox user namespace");
if (setns(sandboxMountNamespace.get(), 0) == -1) if (setns(sandboxMountNamespace.get(), 0) == -1)
throw SysError("entering sandbox mount namespace"); throw SysError("entering sandbox mount namespace");

View file

@ -27,9 +27,10 @@ struct LocalDerivationGoal : public DerivationGoal
/* Pipe for synchronising updates to the builder namespaces. */ /* Pipe for synchronising updates to the builder namespaces. */
Pipe userNamespaceSync; Pipe userNamespaceSync;
/* The mount namespace of the builder, used to add additional /* The mount namespace and user namespace of the builder, used to add additional
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;
AutoCloseFD sandboxUserNamespace;
/* On Linux, whether we're doing the build in its own user /* On Linux, whether we're doing the build in its own user
namespace. */ namespace. */