From 877fb29635370f3ebbdfd0211460bc66347269ea Mon Sep 17 00:00:00 2001 From: aszlig Date: Fri, 11 Sep 2020 18:34:13 +0200 Subject: sandbox: Allow to enable/disable namespaces While the sandbox was initially written for games, I now use the implementation for other things, such as sandboxing database management systems inside "nix develop". However, both MariaDB and PostgreSQL do not like it very much if for example IPC is too restricted and if the PID file contains the PID of the process inside the namespace. Additionally I always wanted to have a way to enable network namespaces for games as well, so this is a good occasion to make them configurable. Of course, since we need the mount and user namespaces to implement our sandbox in the first place, we can't allow users to disable these namespaces, but for everything else, we now have a new "namespaces" attribute. Signed-off-by: aszlig --- pkgs/build-support/build-sandbox/default.nix | 23 +++++++++++++++++++++-- pkgs/build-support/build-sandbox/src/Makefile | 2 ++ pkgs/build-support/build-sandbox/src/setup.c | 3 +-- 3 files changed, 24 insertions(+), 4 deletions(-) (limited to 'pkgs') diff --git a/pkgs/build-support/build-sandbox/default.nix b/pkgs/build-support/build-sandbox/default.nix index 0e1d4a4d..50b8f78f 100644 --- a/pkgs/build-support/build-sandbox/default.nix +++ b/pkgs/build-support/build-sandbox/default.nix @@ -16,6 +16,25 @@ let # TODO: get rid of nix & pkg-config if this is enabled (in the Makefile) fullNixStore = attrs.fullNixStore or false; + # The mount and user namespaces are needed for this functionality, so these + # namespaces are always enabled. + # + # However, the following namespaces can be enabled/disabled: + # +----------------+---------+--------------------------------------+ + # | Attribute path | Default | Isolates | + # +----------------+---------+--------------------------------------+ + # | namespaces.pid | true | Process IDs | + # | namespaces.uts | true | Hostname and NIS domain name | + # | namespaces.ipc | true | System V IPC, POSIX message queues | + # | namespaces.net | false | Network devices, stacks, ports, etc. | + # +----------------+---------+--------------------------------------+ + extraNamespaceFlags = let + flags = lib.optional (attrs.namespaces.pid or true) "CLONE_NEWPID" + ++ lib.optional (attrs.namespaces.uts or true) "CLONE_NEWUTS" + ++ lib.optional (attrs.namespaces.ipc or true) "CLONE_NEWIPC" + ++ lib.optional (attrs.namespaces.net or false) "CLONE_NEWNET"; + in if flags == [] then "0" else lib.concatStringsSep "|" flags; + # Create code snippets for params.c to add extra_mount() calls. mkExtraMountParams = isRequired: lib.concatMapStringsSep "\n" (extra: let escaped = lib.escape ["\\" "\""] extra; @@ -80,8 +99,8 @@ in stdenv.mkDerivation ({ nativeBuildInputs = [ pkgconfig ]; buildInputs = [ boost nix ]; - makeFlags = [ "BINDIR=${drv}/bin" ] + makeFlags = [ "BINDIR=${drv}/bin" "EXTRA_NS_FLAGS=${extraNamespaceFlags}" ] ++ lib.optional allowBinSh "BINSH_EXECUTABLE=${dash}/bin/dash" ++ lib.optional fullNixStore "FULL_NIX_STORE=1"; -} // removeAttrs attrs [ "paths" "allowBinSh" ]) +} // removeAttrs attrs [ "namespaces" "paths" "allowBinSh" ]) diff --git a/pkgs/build-support/build-sandbox/src/Makefile b/pkgs/build-support/build-sandbox/src/Makefile index 8e1218f6..ebe66c0e 100644 --- a/pkgs/build-support/build-sandbox/src/Makefile +++ b/pkgs/build-support/build-sandbox/src/Makefile @@ -6,6 +6,8 @@ CFLAGS = -g -Wall -std=gnu11 -DFS_ROOT_DIR=\"$(out)\" CXXFLAGS = -g -Wall -std=c++14 `pkg-config --cflags nix-main` LDFLAGS = -Wl,--copy-dt-needed-entries `pkg-config --libs nix-main` +CFLAGS += -DEXTRA_NS_FLAGS="$(EXTRA_NS_FLAGS)" + ifdef FULL_NIX_STORE CFLAGS += -DFULL_NIX_STORE else diff --git a/pkgs/build-support/build-sandbox/src/setup.c b/pkgs/build-support/build-sandbox/src/setup.c index 98205710..dc8bbf14 100644 --- a/pkgs/build-support/build-sandbox/src/setup.c +++ b/pkgs/build-support/build-sandbox/src/setup.c @@ -850,8 +850,7 @@ bool setup_sandbox(void) close(sync_pipe[0]); _exit(write_maps(parent_pid) ? 0 : 1); default: - if (unshare(CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWPID | - CLONE_NEWUTS | CLONE_NEWIPC) == -1) { + if (unshare(CLONE_NEWNS | CLONE_NEWUSER | EXTRA_NS_FLAGS) == -1) { perror("unshare"); if (write(sync_pipe[1], "X", 1) == -1) perror("signal child exit"); -- cgit 1.4.1