Linux sandbox: Fix compatibility with older kernels

This commit is contained in:
Eelco Dolstra 2017-05-08 15:42:59 +02:00
parent ebfceeb333
commit 00b286275c
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
2 changed files with 24 additions and 16 deletions

View file

@ -2390,17 +2390,14 @@ void DerivationGoal::runChild()
/* Bind-mount all the directories from the "host"
filesystem that we want in the chroot
environment. */
for (auto & i : dirsInChroot) {
struct stat st;
Path source = i.second.source;
Path target = chrootRootDir + i.first;
if (source == "/proc") continue; // backwards compatibility
auto doBind = [&](const Path & source, const Path & target, bool optional = false) {
debug(format("bind mounting %1% to %2%") % source % target);
struct stat st;
if (stat(source.c_str(), &st) == -1) {
if (i.second.optional && errno == ENOENT)
continue;
if (optional && errno == ENOENT)
return;
else
throw SysError(format("getting attributes of path %1%") % source);
throw SysError("getting attributes of path %1%", source);
}
if (S_ISDIR(st.st_mode))
createDirs(target);
@ -2409,7 +2406,12 @@ void DerivationGoal::runChild()
writeFile(target, "");
}
if (mount(source.c_str(), target.c_str(), "", MS_BIND | MS_REC, 0) == -1)
throw SysError(format("bind mount from %1% to %2% failed") % source % target);
throw SysError("bind mount from %1% to %2% failed", source, target);
};
for (auto & i : dirsInChroot) {
if (i.second.source == "/proc") continue; // backwards compatibility
doBind(i.second.source, chrootRootDir + i.first, i.second.optional);
}
/* Bind a new instance of procfs on /proc. */
@ -2431,13 +2433,19 @@ void DerivationGoal::runChild()
!pathExists(chrootRootDir + "/dev/ptmx")
&& !dirsInChroot.count("/dev/pts"))
{
if (mount("none", (chrootRootDir + "/dev/pts").c_str(), "devpts", 0, "newinstance,mode=0620") == -1)
throw SysError("mounting /dev/pts");
if (mount("none", (chrootRootDir + "/dev/pts").c_str(), "devpts", 0, "newinstance,mode=0620") == 0)
{
createSymlink("/dev/pts/ptmx", chrootRootDir + "/dev/ptmx");
/* Make sure /dev/pts/ptmx is world-writable. With some
Linux versions, it is created with permissions 0. */
chmod_(chrootRootDir + "/dev/pts/ptmx", 0666);
} else {
if (errno != EINVAL)
throw SysError("mounting /dev/pts");
doBind("/dev/pts", "/dev/pts");
doBind("/dev/ptmx", "/dev/ptmx");
}
}
/* Do the chroot(). */

View file

@ -16,7 +16,7 @@ rm -rf $TEST_ROOT/store0
export NIX_STORE_DIR=/my/store
export NIX_REMOTE="local?root=$TEST_ROOT/store0"
outPath=$( nix-build dependencies.nix --no-out-link --option build-sandbox-paths /nix/store)
outPath=$(nix-build dependencies.nix --no-out-link --option build-sandbox-paths /nix/store)
[[ $outPath =~ /my/store/.*-dependencies ]]