about summary refs log tree commit diff
path: root/pkgs/build-support
diff options
context:
space:
mode:
authoraszlig <aszlig@nix.build>2018-07-22 07:04:55 +0200
committeraszlig <aszlig@nix.build>2018-07-22 07:04:55 +0200
commitdb25b6ad5a9abf3c3edd34d980d9ec32604eead7 (patch)
tree846d1dad9b0159ddfb82425eba58c96289492b49 /pkgs/build-support
parentc5e28ba680458cdf094839969a7009eb05d3fb41 (diff)
pkgs/sandbox: Support overlaying files at runtime
This introduces a new environment variable called
NIX_SANDBOX_DEBUG_INJECT_FILES. The name is intentionally very long so
that people hopefully *only* use it for debugging.

What this does is to just bind-mount the given source file to a given
destination file in the chroot.

For example:

  NIX_SANDBOX_DEBUG_INJECT_FILES=/foo/bar=/bar/foo somethingSandboxed

The file /foo/bar outside of the sandbox will be bind-mounted to
/bar/foo within the sandbox. Several files can be separated via colon.

Of course the most interesting use case here (and the reason for this
feature) is that we can overlay files in the Nix store without the need
to rebuild anything, so we can quickly patch specific files.

In my case I'm using this so I can use radare2 to patch the assembly of
some binaries quickly for debugging/reverse engineering.

Signed-off-by: aszlig <aszlig@nix.build>
Diffstat (limited to 'pkgs/build-support')
-rw-r--r--pkgs/build-support/build-sandbox/src/setup.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/pkgs/build-support/build-sandbox/src/setup.c b/pkgs/build-support/build-sandbox/src/setup.c
index e4304b1f..d95927dc 100644
--- a/pkgs/build-support/build-sandbox/src/setup.c
+++ b/pkgs/build-support/build-sandbox/src/setup.c
@@ -688,6 +688,48 @@ static bool setup_runtime_paths(void)
     return true;
 }
 
+static bool setup_runtime_debug(void)
+{
+    char *injected_files, *buf, *ptr, *equals, *target;
+
+    if ((injected_files = getenv("NIX_SANDBOX_DEBUG_INJECT_FILES")) == NULL)
+        return true;
+
+    if ((buf = strdup(injected_files)) == NULL) {
+        perror("strdup NIX_SANDBOX_DEBUG_INJECT_FILES");
+        return false;
+    }
+
+    ptr = strtok(buf, ":");
+
+    while (ptr != NULL) {
+        if ((equals = strchr(ptr, '=')) != NULL) {
+            *equals = '\0';
+
+            if ((target = get_mount_target(equals + 1)) == NULL) {
+                free(buf);
+                return false;
+            }
+
+            if (mount(ptr, target, "", MS_BIND, NULL) == -1) {
+                fprintf(stderr, "mount injected file %s to %s: %s\n",
+                        ptr, target, strerror(errno));
+                free(target);
+                free(buf);
+                return false;
+            }
+
+            free(target);
+            fprintf(stderr, "Injected file '%s' to '%s'.\n", ptr, equals + 1);
+        }
+
+        ptr = strtok(NULL, ":");
+    }
+
+    free(buf);
+    return true;
+}
+
 static bool setup_chroot(void)
 {
     int mflags;
@@ -729,6 +771,9 @@ static bool setup_chroot(void)
     if (!setup_xauthority())
         return false;
 
+    if (!setup_runtime_debug())
+        return false;
+
     if (chroot(FS_ROOT_DIR) == -1) {
         perror("chroot");
         return false;