Add --argv0 option
Fixes containers/bubblewrap#91 Add the ability to overwrite argv[0] when starting a process in a container. Using --argv0 to be consistent with ld.so --argv0. Overwriting argv[0] is useful as some tools change their behavior based on the value of argv[0]. For example, when bash is symlinked to sh it behaves as sh. Similarly, unxz is a symlink to xz and changes the default from compressing to decompressing. An extreme example is on many systems, date, df, cat and so on are all symlinks to the coreutils binary. Example usage: bwrap --bind / / --argv0 sh bash Signed-off-by: Jonathan Wright <quaggy@gmail.com>
This commit is contained in:
23
bubblewrap.c
23
bubblewrap.c
@@ -72,6 +72,7 @@ static const char *opt_exec_label = NULL;
|
|||||||
static const char *opt_file_label = NULL;
|
static const char *opt_file_label = NULL;
|
||||||
static bool opt_as_pid_1;
|
static bool opt_as_pid_1;
|
||||||
|
|
||||||
|
static const char *opt_argv0 = NULL;
|
||||||
static const char *opt_chdir_path = NULL;
|
static const char *opt_chdir_path = NULL;
|
||||||
static bool opt_assert_userns_disabled = FALSE;
|
static bool opt_assert_userns_disabled = FALSE;
|
||||||
static bool opt_disable_userns = FALSE;
|
static bool opt_disable_userns = FALSE;
|
||||||
@@ -309,6 +310,7 @@ usage (int ecode, FILE *out)
|
|||||||
" --help Print this help\n"
|
" --help Print this help\n"
|
||||||
" --version Print version\n"
|
" --version Print version\n"
|
||||||
" --args FD Parse NUL-separated args from FD\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"
|
" --unshare-all Unshare every namespace we support by default\n"
|
||||||
" --share-net Retain the network namespace (can only combine with --unshare-all)\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"
|
" --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;
|
argv += 1;
|
||||||
argc -= 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)
|
else if (strcmp (arg, "--unshare-all") == 0)
|
||||||
{
|
{
|
||||||
/* Keep this in order with the older (legacy) --unshare arguments,
|
/* Keep this in order with the older (legacy) --unshare arguments,
|
||||||
@@ -2641,6 +2655,7 @@ main (int argc,
|
|||||||
int res UNUSED;
|
int res UNUSED;
|
||||||
cleanup_free char *args_data UNUSED = NULL;
|
cleanup_free char *args_data UNUSED = NULL;
|
||||||
int intermediate_pids_sockets[2] = {-1, -1};
|
int intermediate_pids_sockets[2] = {-1, -1};
|
||||||
|
const char *exec_path = NULL;
|
||||||
|
|
||||||
/* Handle --version early on before we try to acquire/drop
|
/* Handle --version early on before we try to acquire/drop
|
||||||
* any capabilities so it works in a build environment;
|
* any capabilities so it works in a build environment;
|
||||||
@@ -3351,7 +3366,11 @@ main (int argc,
|
|||||||
we don't want to error out here */
|
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)
|
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]
|
/* Ignore res, if e.g. the parent died and closed setup_finished_pipe[0]
|
||||||
we don't want to error out here */
|
we don't want to error out here */
|
||||||
}
|
}
|
||||||
die_with_error ("execvp %s", argv[0]);
|
die_with_error ("execvp %s", exec_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -92,6 +92,10 @@
|
|||||||
multiple sources.
|
multiple sources.
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--argv0 <arg choice="plain">VALUE</arg></option></term>
|
||||||
|
<listitem><para>Set argv[0] to the value <arg choice="plain">VALUE</arg> before running the program</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
<para>Options related to kernel namespaces:</para>
|
<para>Options related to kernel namespaces:</para>
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
@@ -32,6 +32,7 @@ _bwrap() {
|
|||||||
$boolean_optons
|
$boolean_optons
|
||||||
--add-seccomp-fd
|
--add-seccomp-fd
|
||||||
--args
|
--args
|
||||||
|
--argv0
|
||||||
--bind
|
--bind
|
||||||
--bind-data
|
--bind-data
|
||||||
--block-fd
|
--block-fd
|
||||||
|
@@ -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"'
|
'--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]'
|
'--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"'
|
'--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]'
|
'--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-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'
|
'--bind[Bind mount the host path SRC on DEST]:source:_files:destination:_files'
|
||||||
|
@@ -8,7 +8,7 @@ srcd=$(cd $(dirname "$0") && pwd)
|
|||||||
|
|
||||||
bn=$(basename "$0")
|
bn=$(basename "$0")
|
||||||
|
|
||||||
echo "1..58"
|
echo "1..59"
|
||||||
|
|
||||||
# Test help
|
# Test help
|
||||||
${BWRAP} --help > help.txt
|
${BWRAP} --help > help.txt
|
||||||
@@ -532,4 +532,12 @@ echo "PWD=$(pwd -P)" > reference
|
|||||||
assert_files_equal stdout reference
|
assert_files_equal stdout reference
|
||||||
echo "ok - environment manipulation"
|
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"
|
echo "ok - End of test"
|
||||||
|
Reference in New Issue
Block a user