diff --git a/bubblewrap.c b/bubblewrap.c
index de06305..267b369 100644
--- a/bubblewrap.c
+++ b/bubblewrap.c
@@ -72,6 +72,7 @@ static const char *opt_exec_label = NULL;
static const char *opt_file_label = NULL;
static bool opt_as_pid_1;
+static const char *opt_argv0 = NULL;
static const char *opt_chdir_path = NULL;
static bool opt_assert_userns_disabled = FALSE;
static bool opt_disable_userns = FALSE;
@@ -309,6 +310,7 @@ usage (int ecode, FILE *out)
" --help Print this help\n"
" --version Print version\n"
" --args FD Parse NUL-separated args from FD\n"
+ " --argv0 VALUE Set argv[0] to the value VALUE before running the program\n"
" --unshare-all Unshare every namespace we support by default\n"
" --share-net Retain the network namespace (can only combine with --unshare-all)\n"
" --unshare-user Create new user namespace (may be automatically implied if not setuid)\n"
@@ -1728,6 +1730,18 @@ parse_args_recurse (int *argcp,
argv += 1;
argc -= 1;
}
+ else if (strcmp (arg, "--argv0") == 0)
+ {
+ if (argc < 2)
+ die ("--argv0 takes one argument");
+
+ if (opt_argv0 != NULL)
+ die ("--argv0 used multiple times");
+
+ opt_argv0 = argv[1];
+ argv++;
+ argc--;
+ }
else if (strcmp (arg, "--unshare-all") == 0)
{
/* Keep this in order with the older (legacy) --unshare arguments,
@@ -2641,6 +2655,7 @@ main (int argc,
int res UNUSED;
cleanup_free char *args_data UNUSED = NULL;
int intermediate_pids_sockets[2] = {-1, -1};
+ const char *exec_path = NULL;
/* Handle --version early on before we try to acquire/drop
* any capabilities so it works in a build environment;
@@ -3351,7 +3366,11 @@ main (int argc,
we don't want to error out here */
}
- if (execvp (argv[0], argv) == -1)
+ exec_path = argv[0];
+ if (opt_argv0 != NULL)
+ argv[0] = (char *) opt_argv0;
+
+ if (execvp (exec_path, argv) == -1)
{
if (setup_finished_pipe[1] != -1)
{
@@ -3362,7 +3381,7 @@ main (int argc,
/* Ignore res, if e.g. the parent died and closed setup_finished_pipe[0]
we don't want to error out here */
}
- die_with_error ("execvp %s", argv[0]);
+ die_with_error ("execvp %s", exec_path);
}
return 0;
diff --git a/bwrap.xml b/bwrap.xml
index 9d770ac..e655524 100644
--- a/bwrap.xml
+++ b/bwrap.xml
@@ -92,6 +92,10 @@
multiple sources.
+
+
+ Set argv[0] to the value VALUE before running the program
+ Options related to kernel namespaces:
diff --git a/completions/bash/bwrap b/completions/bash/bwrap
index ca18d89..e6d2846 100644
--- a/completions/bash/bwrap
+++ b/completions/bash/bwrap
@@ -32,6 +32,7 @@ _bwrap() {
$boolean_optons
--add-seccomp-fd
--args
+ --argv0
--bind
--bind-data
--block-fd
diff --git a/completions/zsh/_bwrap b/completions/zsh/_bwrap
index a2e2caf..fbddda4 100644
--- a/completions/zsh/_bwrap
+++ b/completions/zsh/_bwrap
@@ -29,6 +29,7 @@ _bwrap_args=(
'--add-seccomp-fd[Load and use seccomp rules from FD]: :_guard "[0-9]#" "file descriptor to read seccomp rules from"'
'--assert-userns-disabled[Fail unless further use of user namespace inside sandbox is disabled]'
'--args[Parse NUL-separated args from FD]: :_guard "[0-9]#" "file descriptor with NUL-separated arguments"'
+ '--argv0[Set argv0 to the value VALUE before running the program]:value:'
'--as-pid-1[Do not install a reaper process with PID=1]'
'--bind-try[Equal to --bind but ignores non-existent SRC]:source:_files:destination:_files'
'--bind[Bind mount the host path SRC on DEST]:source:_files:destination:_files'
diff --git a/tests/test-run.sh b/tests/test-run.sh
index a90f0b1..2d9d385 100755
--- a/tests/test-run.sh
+++ b/tests/test-run.sh
@@ -8,7 +8,7 @@ srcd=$(cd $(dirname "$0") && pwd)
bn=$(basename "$0")
-echo "1..58"
+echo "1..59"
# Test help
${BWRAP} --help > help.txt
@@ -532,4 +532,12 @@ echo "PWD=$(pwd -P)" > reference
assert_files_equal stdout reference
echo "ok - environment manipulation"
+$RUN sh -c 'echo $0' > stdout
+assert_file_has_content stdout sh
+$RUN --argv0 sh sh -c 'echo $0' > stdout
+assert_file_has_content stdout sh
+$RUN --argv0 right sh -c 'echo $0' > stdout
+assert_file_has_content stdout right
+echo "ok - argv0 manipulation"
+
echo "ok - End of test"