about summary refs log tree commit diff
path: root/src/libstore/build.cc
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2012-08-20T19·27-0400
committerEelco Dolstra <eelco.dolstra@logicblox.com>2012-08-20T19·27-0400
commit56e30e161cd309addb5aa95ba02a8d3371846228 (patch)
tree55096253401937146eb89c8ef22433f68d63c3e4 /src/libstore/build.cc
parentf0eab0636b73a4f16b7639d30956d9072d5573cb (diff)
In the chroot, make all mounted filesystems private
This is required on systemd, which mounts filesystems as "shared"
subtrees.  Changes to shared trees in a private mount namespace are
propagated to the outside world, which is bad.
Diffstat (limited to 'src/libstore/build.cc')
-rw-r--r--src/libstore/build.cc18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 9da8084bf5..0ed69614b8 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -1853,6 +1853,24 @@ void DerivationGoal::initChild()
             char domainname[] = "(none)"; // kernel default
             setdomainname(domainname, sizeof(domainname));
 
+            /* Make all filesystems private.  This is necessary
+               because subtrees may have been mounted as "shared"
+               (MS_SHARED).  (Systemd does this, for instance.)  Even
+               though we have a private mount namespace, mounting
+               filesystems on top of a shared subtree still propagates
+               outside of the namespace.  Making a subtree private is
+               local to the namespace, though, so setting MS_PRIVATE
+               does not affect the outside world. */
+            Strings mounts = tokenizeString(readFile("/proc/self/mountinfo", true), "\n");
+            foreach (Strings::iterator, i, mounts) {
+                Strings fields = tokenizeString(*i, " ");
+                assert(fields.size() >= 5);
+                Strings::iterator j = fields.begin();
+                std::advance(j, 4);
+                if (mount(0, j->c_str(), 0, MS_PRIVATE, 0) == -1)
+                    throw SysError(format("unable to make filesystem `%1%' private") % *j);
+            }
+
             /* Bind-mount all the directories from the "host"
                filesystem that we want in the chroot
                environment. */