about summary refs log tree commit diff
path: root/pkgs/build-support
diff options
context:
space:
mode:
authoraszlig <aszlig@nix.build>2019-03-23 21:13:38 +0100
committeraszlig <aszlig@nix.build>2019-03-23 21:13:38 +0100
commitd90a7cf68d5cd5b625756ff258f3c99754d6880d (patch)
tree442d45ce791e9d5ca6f184b3a3d42de20f71a9a9 /pkgs/build-support
parent3f2496cd7299bfe54a787cde4aec42b84494a7d6 (diff)
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 <aszlig@nix.build>
Diffstat (limited to 'pkgs/build-support')
-rw-r--r--pkgs/build-support/build-sandbox/default.nix15
-rw-r--r--pkgs/build-support/build-sandbox/src/Makefile3
-rw-r--r--pkgs/build-support/build-sandbox/src/setup.c20
3 files changed, 33 insertions, 5 deletions
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;