about summary refs log tree commit diff
path: root/src/libstore
diff options
context:
space:
mode:
authoraszlig <aszlig@redmoonstudios.org>2016-11-11T03·59+0100
committeraszlig <aszlig@redmoonstudios.org>2016-11-16T15·48+0100
commite8838713df29d94529ea4d7865180e936393340b (patch)
tree47462a8b7fb7b079a23a9cc8f2195847564a59d3 /src/libstore
parentb77fb8acb57fee1b6decab818f0893832b4cf440 (diff)
Run builds as root in user namespace again
This reverts commit ff0c0b645cc1448959126185bb2fafe41cf0bddf.

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>
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build.cc45
1 files changed, 16 insertions, 29 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 61286ceac9e4..ed9d48378f00 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -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;