diff options
-rw-r--r-- | src/libstore/build.cc | 18 | ||||
-rw-r--r-- | src/libutil/util.cc | 4 | ||||
-rw-r--r-- | src/libutil/util.hh | 2 |
3 files changed, 21 insertions, 3 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 9da8084bf5c7..0ed69614b80b 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 9d8e4afed37d..fe4fedfa597d 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 dc38a53ca2fe..22992bbafee7 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); |