summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2019-04-02 10:04:16 +0200
committerLennart Poettering <lennart@poettering.net>2019-04-02 10:19:17 +0200
commited179fd71030ddd657500591dac37e7499fc7b2c (patch)
tree2f3beac65129961eeb5491f68a2576f75fba3c63
parentbuild: install /etc/systemd/{system,user}-generators (diff)
downloadsystemd-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
-rw-r--r--src/tty-ask-password-agent/tty-ask-password-agent.c33
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) {
/*