]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tty-ask-password: copy argv[] before forking child
authorLennart Poettering <lennart@poettering.net>
Tue, 2 Apr 2019 08:04:16 +0000 (10:04 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 2 Apr 2019 08:19:17 +0000 (10:19 +0200)
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
src/tty-ask-password-agent/tty-ask-password-agent.c

index 790177d6810202449e1e1afafa120fb82efd569a..d4ce904f3fb236198130061e568e293ab77a23b1 100644 (file)
@@ -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) {
                 /*