diff options
author | Lennart Poettering <lennart@poettering.net> | 2019-04-02 10:04:16 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2019-04-02 10:19:17 +0200 |
commit | ed179fd71030ddd657500591dac37e7499fc7b2c (patch) | |
tree | 2f3beac65129961eeb5491f68a2576f75fba3c63 /src/tty-ask-password-agent | |
parent | build: install /etc/systemd/{system,user}-generators (diff) | |
download | systemd-ed179fd71030ddd657500591dac37e7499fc7b2c.tar.xz systemd-ed179fd71030ddd657500591dac37e7499fc7b2c.zip |
tty-ask-password: copy argv[] before forking child
Another fix in style of bd169c2be0fbdaf6eb2ea7951e650d5e5983fbf6.
Let's also avoid strjoina() in a loop (i.e. stack allocation). While in
this specific caseone could get away with it (since we'd immediately
afterwards leave the loop) it's still ugly, and every static checker
would be totally within its rights to complain.
Also, let's simplify things by not relying on argc, since it's redundant
anyway, and it's nicer to just treat things as NULL terminated strv
array.
Fixes: #12180
Diffstat (limited to 'src/tty-ask-password-agent')
-rw-r--r-- | src/tty-ask-password-agent/tty-ask-password-agent.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c index 790177d681..d4ce904f3f 100644 --- a/src/tty-ask-password-agent/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent/tty-ask-password-agent.c @@ -695,7 +695,8 @@ static int parse_argv(int argc, char *argv[]) { * If one of the tasks does handle a password, the remaining tasks * will be terminated. */ -static int ask_on_this_console(const char *tty, pid_t *ret_pid, int argc, char *argv[]) { +static int ask_on_this_console(const char *tty, pid_t *ret_pid, char *argv[]) { + _cleanup_strv_free_ char **arguments = NULL; struct sigaction sig = { .sa_handler = nop_signal_handler, .sa_flags = SA_NOCLDSTOP | SA_RESTART, @@ -703,6 +704,10 @@ static int ask_on_this_console(const char *tty, pid_t *ret_pid, int argc, char * pid_t pid; int r; + arguments = strv_copy(argv); + if (!arguments) + return log_oom(); + assert_se(sigprocmask_many(SIG_UNBLOCK, NULL, SIGHUP, SIGCHLD, -1) >= 0); assert_se(sigemptyset(&sig.sa_mask) >= 0); @@ -715,18 +720,24 @@ static int ask_on_this_console(const char *tty, pid_t *ret_pid, int argc, char * if (r < 0) return r; if (r == 0) { - int ac; + char **i; assert_se(prctl(PR_SET_PDEATHSIG, SIGHUP) >= 0); - for (ac = 0; ac < argc; ac++) { - if (streq(argv[ac], "--console")) { - argv[ac] = strjoina("--console=", tty); - break; + STRV_FOREACH(i, arguments) { + char *k; + + if (!streq(*i, "--console")) + continue; + + k = strjoin("--console=", tty); + if (!k) { + log_oom(); + _exit(EXIT_FAILURE); } - } - assert(ac < argc); + free_and_replace(*i, k); + } execv(SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, argv); _exit(EXIT_FAILURE); @@ -788,7 +799,7 @@ static void terminate_agents(Set *pids) { } } -static int ask_on_consoles(int argc, char *argv[]) { +static int ask_on_consoles(char *argv[]) { _cleanup_set_free_ Set *pids = NULL; _cleanup_strv_free_ char **consoles = NULL; siginfo_t status = {}; @@ -806,7 +817,7 @@ static int ask_on_consoles(int argc, char *argv[]) { /* Start an agent on each console. */ STRV_FOREACH(tty, consoles) { - r = ask_on_this_console(*tty, &pid, argc, argv); + r = ask_on_this_console(*tty, &pid, argv); if (r < 0) return r; @@ -851,7 +862,7 @@ static int run(int argc, char *argv[]) { /* * Spawn a separate process for each console device. */ - return ask_on_consoles(argc, argv); + return ask_on_consoles(argv); if (arg_device) { /* |