diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2012-08-20 15:27:30 -0400 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2012-08-20 15:27:30 -0400 |
commit | 56e30e161cd309addb5aa95ba02a8d3371846228 (patch) | |
tree | 55096253401937146eb89c8ef22433f68d63c3e4 /src/libstore/build.cc | |
parent | f0eab0636b73a4f16b7639d30956d9072d5573cb (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.cc | 18 |
1 files changed, 18 insertions, 0 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. */ |