From db25b6ad5a9abf3c3edd34d980d9ec32604eead7 Mon Sep 17 00:00:00 2001 From: aszlig Date: Sun, 22 Jul 2018 07:04:55 +0200 Subject: 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 --- pkgs/build-support/build-sandbox/src/setup.c | 45 ++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'pkgs/build-support/build-sandbox/src') 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; -- cgit 1.4.1