about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--pkgs/build-support/build-sandbox/src/setup.c23
-rw-r--r--tests/sandbox.nix8
2 files changed, 29 insertions, 2 deletions
diff --git a/pkgs/build-support/build-sandbox/src/setup.c b/pkgs/build-support/build-sandbox/src/setup.c
index d95927dc..cf73d3e8 100644
--- a/pkgs/build-support/build-sandbox/src/setup.c
+++ b/pkgs/build-support/build-sandbox/src/setup.c
@@ -747,9 +747,14 @@ static bool setup_chroot(void)
     if (!bind_mount("/dev", false, false, false))
         return false;
 
-    if (!bind_mount("/proc", false, false, false))
+    if (!makedirs(FS_ROOT_DIR "/proc", false))
         return false;
 
+    if (mount("none", FS_ROOT_DIR "/proc", "proc", 0, NULL) == -1) {
+        perror("mount /proc");
+        return false;
+    }
+
     if (!bind_mount("/sys", false, false, false))
         return false;
 
@@ -815,7 +820,8 @@ bool setup_sandbox(void)
             close(sync_pipe[0]);
             _exit(write_maps(parent_pid) ? 0 : 1);
         default:
-            if (unshare(CLONE_NEWNS | CLONE_NEWUSER) == -1) {
+            if (unshare(CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWPID |
+                        CLONE_NEWUTS | CLONE_NEWIPC) == -1) {
                 perror("unshare");
                 if (write(sync_pipe[1], "X", 1) == -1)
                     perror("signal child exit");
@@ -830,6 +836,19 @@ bool setup_sandbox(void)
             return false;
     }
 
+    if ((pid = fork()) == -1) {
+        perror("fork PID namespace");
+        return false;
+    }
+
+    /* Just wait in the parent until the child exits. We need to fork because
+     * otherwise we can't mount /proc in the right PID namespace.
+     */
+    if (pid > 0) {
+        waitpid(pid, NULL, 0);
+        _exit(1);
+    }
+
     cached_paths = new_path_cache();
 
     if (!setup_chroot()) {
diff --git a/tests/sandbox.nix b/tests/sandbox.nix
index f3013b2e..e92099bf 100644
--- a/tests/sandbox.nix
+++ b/tests/sandbox.nix
@@ -37,6 +37,11 @@
           # Should fail because we can't access the host's PATH
           ! echo foo | grep -qF foo
 
+          # Write PID information to files, so that we can later verify whether
+          # we were in a PID namespace.
+          echo $$ > /home/foo/.cache/xdg/ownpid
+          ls -d1 /proc/[0-9]* > /home/foo/.cache/xdg/procpids
+
           # Check whether we can access files behind nested storepaths that are
           # symlinks.
           lfile="$(< ${mkNestedLinksTo (pkgs.writeText "target" "file")})"
@@ -116,5 +121,8 @@
     $machine->succeed('grep -qF XDG1 /home/foo/.local/share/xdg/1');
     $machine->succeed('grep -qF XDG2 /home/foo/.config/xdg/2');
     $machine->succeed('grep -qF XDG3 /home/foo/.cache/xdg/3');
+
+    $machine->succeed('test "$(< /home/foo/.cache/xdg/procpids)" = /proc/1');
+    $machine->succeed('test "$(< /home/foo/.cache/xdg/ownpid)" = 1');
   '';
 }