Run builds as root in user namespace again

This reverts commit ff0c0b645c.

We're going to use seccomp to allow "cp -p" and force chown-related
syscalls to always return 0.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
This commit is contained in:
aszlig 2016-11-11 04:59:48 +01:00
parent b77fb8acb5
commit e8838713df
No known key found for this signature in database
GPG key ID: 1DE8E48E57DB5436

View file

@ -811,9 +811,6 @@ 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);
@ -1956,18 +1953,14 @@ void DerivationGoal::startBuilder()
createDirs(chrootRootDir + "/etc");
writeFile(chrootRootDir + "/etc/passwd",
(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());
"root:x:0:0:Nix build user:/:/noshell\n"
"nobody:x:65534:65534:Nobody:/:/noshell\n");
/* Declare the build user's group so that programs get a consistent
view of the system (e.g., "id -gn"). */
writeFile(chrootRootDir + "/etc/group",
(format(
"root:x:0:\n"
"nixbld:!:%1%:\n"
"nogroup:x:65534:\n") % sandboxGid).str());
"root:x:0:\n"
"nobody:x:65534:\n");
/* Create /etc/hosts with localhost entry. */
if (!fixedOutput)
@ -2149,12 +2142,7 @@ void DerivationGoal::startBuilder()
Pid helper = startProcess([&]() {
/* Drop additional groups here because we can't do it
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)?)*/
after we've created the new user namespace. */
if (getuid() == 0 && setgroups(0, 0) == -1)
throw SysError("setgroups failed");
@ -2187,19 +2175,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 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();
/* 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();
writeFile("/proc/" + std::to_string(pid) + "/uid_map",
(format("%d %d 1") % sandboxUid % hostUid).str());
(format("0 %d 1") % targetUid).str());
writeFile("/proc/" + std::to_string(pid) + "/setgroups", "deny");
writeFile("/proc/" + std::to_string(pid) + "/gid_map",
(format("%d %d 1") % sandboxGid % hostGid).str());
(format("0 %d 1") % targetGid).str());
/* Signal the builder that we've updated its user
namespace. */
@ -2409,12 +2397,11 @@ void DerivationGoal::runChild()
if (rmdir("real-root") == -1)
throw SysError("cannot remove real-root directory");
/* 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)
/* Become root in the user namespace, which corresponds to
the build user or calling user in the parent namespace. */
if (setgid(0) == -1)
throw SysError("setgid failed");
if (setuid(sandboxUid) == -1)
if (setuid(0) == -1)
throw SysError("setuid failed");
setUser = false;