aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2012-08-20 15:27:30 -0400
committerEelco Dolstra <eelco.dolstra@logicblox.com>2012-08-20 15:27:30 -0400
commit56e30e161cd309addb5aa95ba02a8d3371846228 (patch)
tree55096253401937146eb89c8ef22433f68d63c3e4 /src
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')
-rw-r--r--src/libstore/build.cc18
-rw-r--r--src/libutil/util.cc4
-rw-r--r--src/libutil/util.hh2
3 files changed, 21 insertions, 3 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 9da8084bf..0ed69614b 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. */
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 9d8e4afed..fe4fedfa5 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -224,12 +224,12 @@ string readFile(int fd)
}
-string readFile(const Path & path)
+string readFile(const Path & path, bool drain)
{
AutoCloseFD fd = open(path.c_str(), O_RDONLY);
if (fd == -1)
throw SysError(format("opening file `%1%'") % path);
- return readFile(fd);
+ return drain ? drainFD(fd) : readFile(fd);
}
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index dc38a53ca..22992bbaf 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -63,7 +63,7 @@ Strings readDirectory(const Path & path);
/* Read the contents of a file into a string. */
string readFile(int fd);
-string readFile(const Path & path);
+string readFile(const Path & path, bool drain = false);
/* Write a string to a file. */
void writeFile(const Path & path, const string & s);