From d90a7cf68d5cd5b625756ff258f3c99754d6880d Mon Sep 17 00:00:00 2001 From: aszlig Date: Sat, 23 Mar 2019 21:13:38 +0100 Subject: sandbox: Add an option to set up /bin/sh So far I mostly used this implementation for the games we have packaged, where we pretty much patch out all commands that execute external programs. However in order to be useful in a more generic way, it makes sense to provide a /bin/sh implementation, especially when you have to deal with scripting languages. I'm using dash here, because it's a more minimal implementation rather than the default shell (bash) we use in nixpkgs and it practically only needs to be able to run constructs like "/bin/sh -c foo". Signed-off-by: aszlig --- pkgs/build-support/build-sandbox/default.nix | 15 ++++++++++----- pkgs/build-support/build-sandbox/src/Makefile | 3 +++ pkgs/build-support/build-sandbox/src/setup.c | 20 ++++++++++++++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) (limited to 'pkgs/build-support') diff --git a/pkgs/build-support/build-sandbox/default.nix b/pkgs/build-support/build-sandbox/default.nix index 4265d30d..66797268 100644 --- a/pkgs/build-support/build-sandbox/default.nix +++ b/pkgs/build-support/build-sandbox/default.nix @@ -1,4 +1,4 @@ -{ stdenv, lib, pkgconfig, nix, boost }: +{ stdenv, lib, pkgconfig, nix, boost, dash }: drv: { paths ? {}, ... }@attrs: @@ -9,6 +9,8 @@ let pathsWanted = paths.wanted or []; # Paths extracted from PATH-like environment variables, eg. LD_LIBRARY_PATH. pathsRuntimeVars = paths.runtimeVars or []; + # Mount a dash shell in /bin/sh inside the chroot. + allowBinSh = attrs.allowBinSh or false; # Create code snippets for params.c to add extra_mount() calls. mkExtraMountParams = isRequired: lib.concatMapStringsSep "\n" (extra: let @@ -24,7 +26,9 @@ in stdenv.mkDerivation ({ inherit drv; - exportReferencesGraph = [ "sandbox-closure" drv ]; + exportReferencesGraph = + [ "sandbox-closure" drv ] ++ + lib.optionals allowBinSh [ "sandbox-binsh" dash ]; configurePhase = '' runtimeDeps="$(sed -ne ' @@ -43,7 +47,7 @@ in stdenv.mkDerivation ({ y/X/9/ x; n; p; x bcdown - ' ../sandbox-closure | sort -u)" + ' ../sandbox-* | sort -u)" echo '#include "setup.h"' > params.c echo 'bool setup_app_paths(void) {' >> params.c @@ -79,6 +83,7 @@ in stdenv.mkDerivation ({ nativeBuildInputs = [ pkgconfig ]; buildInputs = [ nix boost ]; - makeFlags = [ "BINDIR=${drv}/bin" ]; + makeFlags = [ "BINDIR=${drv}/bin" ] + ++ lib.optional allowBinSh "BINSH_EXECUTABLE=${dash}/bin/dash"; -} // removeAttrs attrs [ "paths" ]) +} // removeAttrs attrs [ "paths" "allowBinSh" ]) diff --git a/pkgs/build-support/build-sandbox/src/Makefile b/pkgs/build-support/build-sandbox/src/Makefile index a5b9b32d..e18ec9d4 100644 --- a/pkgs/build-support/build-sandbox/src/Makefile +++ b/pkgs/build-support/build-sandbox/src/Makefile @@ -8,6 +8,9 @@ NIX_VERSION = `pkg-config --modversion nix-main | \ OBJECTS = nix-query.o path-cache.o params.o setup.o CFLAGS = -g -Wall -std=gnu11 -DFS_ROOT_DIR=\"$(out)\" +ifdef BINSH_EXECUTABLE +CFLAGS += -DBINSH_EXECUTABLE=\"$(BINSH_EXECUTABLE)\" +endif CXXFLAGS = -g -Wall -std=c++14 `pkg-config --cflags nix-main` CXXFLAGS += -DNIX_VERSION=$(NIX_VERSION) LDFLAGS = -Wl,--copy-dt-needed-entries `pkg-config --libs nix-main` diff --git a/pkgs/build-support/build-sandbox/src/setup.c b/pkgs/build-support/build-sandbox/src/setup.c index cf73d3e8..feafd6f6 100644 --- a/pkgs/build-support/build-sandbox/src/setup.c +++ b/pkgs/build-support/build-sandbox/src/setup.c @@ -589,6 +589,21 @@ static bool setup_xauthority(void) return result; } +#ifdef BINSH_EXECUTABLE +static bool setup_binsh(const char *executable) +{ + if (!makedirs(FS_ROOT_DIR "/bin", false)) + return false; + + if (symlink(executable, FS_ROOT_DIR "/bin/sh") == -1) { + fprintf(stderr, "creating symlink from %s to %s: %s\n", + executable, FS_ROOT_DIR "/bin/sh", strerror(errno)); + return false; + } + return true; +} +#endif + static bool is_dir(const char *path) { struct stat sb; @@ -779,6 +794,11 @@ static bool setup_chroot(void) if (!setup_runtime_debug()) return false; +#ifdef BINSH_EXECUTABLE + if (!setup_binsh(BINSH_EXECUTABLE)) + return false; +#endif + if (chroot(FS_ROOT_DIR) == -1) { perror("chroot"); return false; -- cgit 1.4.1