about summary refs log tree commit diff
path: root/pkgs/build-support
diff options
context:
space:
mode:
authoraszlig <aszlig@nix.build>2018-09-20 16:46:49 +0200
committeraszlig <aszlig@nix.build>2018-09-20 16:46:49 +0200
commit3cbf143da6c6213a184b7562555cf0cfee3ca133 (patch)
tree9edc97e8e529d5d5cbfa4bbfe6625753a2c650e1 /pkgs/build-support
parent9490c5a93a6738b6df503fdf67cd4a5e2ec9c95e (diff)
pkgs/sandbox: Add UTS/PID/IPC namespacing
In order to isolate processes even further it's a good idea to not let
them access information about other PIDs, eg. by enumerating /proc.

However, this still bind-mounts /sys from the root namespace, so we
might want to restrict /sys further. For our games however we will need
/sys because it is used to enumerate gamepads and other input devices.

Currently the processes will now be PID 1. I've tested this against a
few games and none of them had problems with that so far, so let's keep
it that way.

Another thing we might want to add and which currently isn't there is a
subreaper, which is useful if we have a process that leaves zombie
processes around.

Signed-off-by: aszlig <aszlig@nix.build>
Diffstat (limited to 'pkgs/build-support')
-rw-r--r--pkgs/build-support/build-sandbox/src/setup.c23
1 files changed, 21 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()) {