aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-05-08 15:42:59 +0200
committerEelco Dolstra <edolstra@gmail.com>2017-05-08 15:42:59 +0200
commit00b286275c1a77458e45bd73528c9ca729cca7f6 (patch)
tree3e252f2668f428538bf08030bad1bfbb249dcd8e
parentebfceeb333120411af46d0af4805f3e7d557159f (diff)
Linux sandbox: Fix compatibility with older kernels
-rw-r--r--src/libstore/build.cc38
-rw-r--r--tests/linux-sandbox.sh2
2 files changed, 24 insertions, 16 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index dc9b9e023..270500d81 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -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");
- createSymlink("/dev/pts/ptmx", chrootRootDir + "/dev/ptmx");
+ 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);
+ /* 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(). */
diff --git a/tests/linux-sandbox.sh b/tests/linux-sandbox.sh
index 740b2c357..54cdef817 100644
--- a/tests/linux-sandbox.sh
+++ b/tests/linux-sandbox.sh
@@ -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 ]]