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.
This commit is contained in:
parent
f0eab0636b
commit
56e30e161c
3 changed files with 21 additions and 3 deletions
|
@ -1853,6 +1853,24 @@ void DerivationGoal::initChild()
|
||||||
char domainname[] = "(none)"; // kernel default
|
char domainname[] = "(none)"; // kernel default
|
||||||
setdomainname(domainname, sizeof(domainname));
|
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"
|
/* Bind-mount all the directories from the "host"
|
||||||
filesystem that we want in the chroot
|
filesystem that we want in the chroot
|
||||||
environment. */
|
environment. */
|
||||||
|
|
|
@ -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);
|
AutoCloseFD fd = open(path.c_str(), O_RDONLY);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
throw SysError(format("opening file `%1%'") % path);
|
throw SysError(format("opening file `%1%'") % path);
|
||||||
return readFile(fd);
|
return drain ? drainFD(fd) : readFile(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ Strings readDirectory(const Path & path);
|
||||||
|
|
||||||
/* Read the contents of a file into a string. */
|
/* Read the contents of a file into a string. */
|
||||||
string readFile(int fd);
|
string readFile(int fd);
|
||||||
string readFile(const Path & path);
|
string readFile(const Path & path, bool drain = false);
|
||||||
|
|
||||||
/* Write a string to a file. */
|
/* Write a string to a file. */
|
||||||
void writeFile(const Path & path, const string & s);
|
void writeFile(const Path & path, const string & s);
|
||||||
|
|
Loading…
Reference in a new issue