[gnome-control-center] user-accounts: run-passwd: Redirect stderr to stdout in the child



commit bb4acf75eff5d9148f01dcb1bf98242a5e9dce37
Author: Pablo Correa Gómez <ablocorrea hotmail com>
Date:   Tue May 17 12:19:08 2022 +0200

    user-accounts: run-passwd: Redirect stderr to stdout in the child
    
    The previous code was prone to race conditions if the child already
    started writing to stdout before the dup2 call happened. This has
    been detected in postmarketOS[1] and I also reproduced it in Alpine
    Linux. Since passwd writes to stderr and linux-pam to stdout, the
    redirection was needed. However, linux-pam was failing with
    "Conversation error" since an fprintf(stdout, ...) call wasn't
    able to write to an already-closed stdout.
    
    This problem is fixed by setting the redirection in the child setup
    function and ignoring the stderr pipe. It also fixes a leak, where
    the stderr fd was simply ignored and never closed.
    
    [1] https://gitlab.com/postmarketOS/pmaports/-/issues/1449

 panels/user-accounts/run-passwd.c | 26 +++++++-------------------
 1 file changed, 7 insertions(+), 19 deletions(-)
---
diff --git a/panels/user-accounts/run-passwd.c b/panels/user-accounts/run-passwd.c
index 86f53d4fc..edbc99830 100644
--- a/panels/user-accounts/run-passwd.c
+++ b/panels/user-accounts/run-passwd.c
@@ -32,6 +32,7 @@
 
 #include <unistd.h>
 #include <errno.h>
+#include <stdio.h>
 #include <string.h>
 #include <sys/wait.h>
 
@@ -136,9 +137,10 @@ child_watch_cb (GPid pid, gint status, PasswdHandler *passwd_handler)
 }
 
 static void
-ignore_sigpipe (gpointer data)
+child_setup_cb (gpointer data)
 {
-        signal (SIGPIPE, SIG_IGN);
+       signal (SIGPIPE, SIG_IGN);
+       dup2 (fileno (stdout), fileno (stderr));
 }
 
 /* Spawn passwd backend
@@ -148,7 +150,7 @@ spawn_passwd (PasswdHandler *passwd_handler, GError **error)
 {
         gchar   *argv[2];
         gchar  **envp;
-        gint    my_stdin, my_stdout, my_stderr;
+        gint    my_stdin, my_stdout;
 
         argv[0] = "/usr/bin/passwd";    /* Is it safe to rely on a hard-coded path? */
         argv[1] = NULL;
@@ -160,12 +162,12 @@ spawn_passwd (PasswdHandler *passwd_handler, GError **error)
                                        argv,                            /* Argument vector */
                                        envp,                            /* Environment */
                                        G_SPAWN_DO_NOT_REAP_CHILD,       /* Flags */
-                                       ignore_sigpipe,                  /* Child setup */
+                                       child_setup_cb,                  /* Child setup */
                                        NULL,                            /* Data to child setup */
                                        &passwd_handler->backend_pid,    /* PID */
                                        &my_stdin,                       /* Stdin */
                                        &my_stdout,                      /* Stdout */
-                                       &my_stderr,                      /* Stderr */
+                                       NULL,                            /* Stderr */
                                        error)) {                        /* GError */
 
                 /* An error occurred */
@@ -178,20 +180,6 @@ spawn_passwd (PasswdHandler *passwd_handler, GError **error)
 
         g_strfreev (envp);
 
-        /* 2>&1 */
-        if (dup2 (my_stderr, my_stdout) == -1) {
-                /* Failed! */
-                g_set_error_literal (error,
-                                     PASSWD_ERROR,
-                                     PASSWD_ERROR_BACKEND,
-                                     strerror (errno));
-
-                /* Clean up */
-                stop_passwd (passwd_handler);
-
-                return FALSE;
-        }
-
         /* Open IO Channels */
         passwd_handler->backend_stdin = g_io_channel_unix_new (my_stdin);
         passwd_handler->backend_stdout = g_io_channel_unix_new (my_stdout);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]