Skip to content

Commit

Permalink
Run builds as root in user namespace again
Browse files Browse the repository at this point in the history
This reverts commit ff0c0b6.

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>
  • Loading branch information
aszlig committed Nov 16, 2016
1 parent b77fb8a commit e883871
Showing 1 changed file with 16 additions and 29 deletions.
45 changes: 16 additions & 29 deletions src/libstore/build.cc
Expand Up @@ -811,9 +811,6 @@ class DerivationGoal : public Goal
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);
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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");

Expand Down Expand Up @@ -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. */
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit e883871

Please sign in to comment.