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. */ 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);
@ -1956,18 +1953,14 @@ 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"
"nixbld:x:%1%:%2%:Nix build user:/:/noshell\n" "nobody:x:65534:65534:Nobody:/:/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"
"nixbld:!:%1%:\n" "nobody:x:65534:\n");
"nogroup:x:65534:\n") % sandboxGid).str());
/* Create /etc/hosts with localhost entry. */ /* Create /etc/hosts with localhost entry. */
if (!fixedOutput) if (!fixedOutput)
@ -2149,12 +2142,7 @@ 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. FIXME: after we've created the new user namespace. */
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");
@ -2187,19 +2175,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 namespace /* Set the UID/GID mapping of the builder's user
such that the sandbox user maps to the build user, or to namespace such that root maps to the build user, or to the
the calling user (if build users are disabled). */ calling user (if build users are disabled). */
uid_t hostUid = buildUser.enabled() ? buildUser.getUID() : getuid(); uid_t targetUid = buildUser.enabled() ? buildUser.getUID() : getuid();
uid_t hostGid = buildUser.enabled() ? buildUser.getGID() : getgid(); uid_t targetGid = buildUser.enabled() ? buildUser.getGID() : getgid();
writeFile("/proc/" + std::to_string(pid) + "/uid_map", 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) + "/setgroups", "deny");
writeFile("/proc/" + std::to_string(pid) + "/gid_map", 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 /* Signal the builder that we've updated its user
namespace. */ namespace. */
@ -2409,12 +2397,11 @@ 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");
/* Switch to the sandbox uid/gid in the user namespace, /* Become root in the user namespace, which corresponds to
which corresponds to the build user or calling user in the build user or calling user in the parent namespace. */
the parent namespace. */ if (setgid(0) == -1)
if (setgid(sandboxGid) == -1)
throw SysError("setgid failed"); throw SysError("setgid failed");
if (setuid(sandboxUid) == -1) if (setuid(0) == -1)
throw SysError("setuid failed"); throw SysError("setuid failed");
setUser = false; setUser = false;