diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2022-08-26 14:58:39 +1000 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2022-08-30 19:43:31 +0200 |
commit | 1392bc5ca0021821aa5838b6624d6246a3e6f26c (patch) | |
tree | 86adbde472efd94f2bcb5a7e3655906665540e62 /pasta.c | |
parent | c188736cd81aab5924073118f11d1b9dc7696382 (diff) | |
download | passt-1392bc5ca0021821aa5838b6624d6246a3e6f26c.tar passt-1392bc5ca0021821aa5838b6624d6246a3e6f26c.tar.gz passt-1392bc5ca0021821aa5838b6624d6246a3e6f26c.tar.bz2 passt-1392bc5ca0021821aa5838b6624d6246a3e6f26c.tar.lz passt-1392bc5ca0021821aa5838b6624d6246a3e6f26c.tar.xz passt-1392bc5ca0021821aa5838b6624d6246a3e6f26c.tar.zst passt-1392bc5ca0021821aa5838b6624d6246a3e6f26c.zip |
Allow pasta to take a command to execute
When not given an existing PID or network namspace to attach to, pasta
spawns a shell. Most commands which can spawn a shell in an altered
environment can also run other commands in that same environment, which can
be useful in automation.
Allow pasta to do the same thing; it can be given an arbitrary command to
run in the network and user namespace which pasta creates. If neither a
command nor an existing PID or netns to attach to is given, continue to
spawn a default shell, as before.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'pasta.c')
-rw-r--r-- | pasta.c | 33 |
1 files changed, 23 insertions, 10 deletions
@@ -108,6 +108,7 @@ netns: struct pasta_setup_ns_arg { struct ctx *c; int euid; + char **argv; }; /** @@ -119,7 +120,6 @@ struct pasta_setup_ns_arg { static int pasta_setup_ns(void *arg) { struct pasta_setup_ns_arg *a = (struct pasta_setup_ns_arg *)arg; - char *shell; if (!a->c->netns_only) { char buf[BUFSIZ]; @@ -139,29 +139,42 @@ static int pasta_setup_ns(void *arg) FWRITE("/proc/sys/net/ipv4/ping_group_range", "0 0", "Cannot set ping_group_range, ICMP requests might fail"); - shell = getenv("SHELL") ? getenv("SHELL") : "/bin/sh"; - if (strstr(shell, "/bash")) - execve(shell, ((char *[]) { shell, "-l", NULL }), environ); - else - execve(shell, ((char *[]) { shell, NULL }), environ); + execvp(a->argv[0], a->argv); - perror("execve"); + perror("execvp"); exit(EXIT_FAILURE); } /** - * pasta_start_ns() - Fork shell in new namespace if target ns is not given + * pasta_start_ns() - Fork command in new namespace if target ns is not given * @c: Execution context + * @argc: Number of arguments for spawned command + * @argv: Command to spawn and arguments */ -void pasta_start_ns(struct ctx *c) +void pasta_start_ns(struct ctx *c, int argc, char *argv[]) { - struct pasta_setup_ns_arg arg = { .c = c, .euid = geteuid() }; + struct pasta_setup_ns_arg arg = { + .c = c, + .euid = geteuid(), + .argv = argv, + }; + char *shell = getenv("SHELL") ? getenv("SHELL") : "/bin/sh"; + char *sh_argv[] = { shell, NULL }; + char *bash_argv[] = { shell, "-l", NULL }; char ns_fn_stack[NS_FN_STACK_SIZE]; c->foreground = 1; if (!c->debug) c->quiet = 1; + if (argc == 0) { + if (strstr(shell, "/bash")) { + arg.argv = bash_argv; + } else { + arg.argv = sh_argv; + } + } + pasta_child_pid = clone(pasta_setup_ns, ns_fn_stack + sizeof(ns_fn_stack) / 2, (c->netns_only ? 0 : CLONE_NEWNET) | |