[gnome-control-center/gnome-42] user-accounts: run-passwd: Redirect stderr to stdout in the child
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/gnome-42] user-accounts: run-passwd: Redirect stderr to stdout in the child
- Date: Mon, 20 Jun 2022 01:45:47 +0000 (UTC)
commit 063d89abe8242160ffe2aeccf644c467920bdf35
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]