b7dd4d
From d6ffd324cc933efec946a3ffbed6fccfe7077203 Mon Sep 17 00:00:00 2001
b7dd4d
From: Lennart Poettering <lennart@poettering.net>
b7dd4d
Date: Mon, 26 Nov 2018 21:07:48 +0100
b7dd4d
Subject: [PATCH] core: be more careful when inheriting stdout fds to stderr
b7dd4d
b7dd4d
We need to compare the fd name/file name if we inherit an fd from stdout
b7dd4d
to stderr. Let's do that.
b7dd4d
b7dd4d
Fixes: #10875
b7dd4d
(cherry picked from commit 41fc585a7a3b8ae857cad5fdad1bc70cdacfa8e5)
b7dd4d
b7dd4d
Related: #2093479
b7dd4d
---
b7dd4d
 src/core/execute.c | 27 +++++++++++++++++++++++++--
b7dd4d
 1 file changed, 25 insertions(+), 2 deletions(-)
b7dd4d
b7dd4d
diff --git a/src/core/execute.c b/src/core/execute.c
b7dd4d
index 9cbb678ac4..b1d8dceb32 100644
b7dd4d
--- a/src/core/execute.c
b7dd4d
+++ b/src/core/execute.c
b7dd4d
@@ -545,6 +545,30 @@ static int setup_input(
b7dd4d
         }
b7dd4d
 }
b7dd4d
 
b7dd4d
+static bool can_inherit_stderr_from_stdout(
b7dd4d
+                const ExecContext *context,
b7dd4d
+                ExecOutput o,
b7dd4d
+                ExecOutput e) {
b7dd4d
+
b7dd4d
+        assert(context);
b7dd4d
+
b7dd4d
+        /* Returns true, if given the specified STDERR and STDOUT output we can directly dup() the stdout fd to the
b7dd4d
+         * stderr fd */
b7dd4d
+
b7dd4d
+        if (e == EXEC_OUTPUT_INHERIT)
b7dd4d
+                return true;
b7dd4d
+        if (e != o)
b7dd4d
+                return false;
b7dd4d
+
b7dd4d
+        if (e == EXEC_OUTPUT_NAMED_FD)
b7dd4d
+                return streq_ptr(context->stdio_fdname[STDOUT_FILENO], context->stdio_fdname[STDERR_FILENO]);
b7dd4d
+
b7dd4d
+        if (IN_SET(e, EXEC_OUTPUT_FILE, EXEC_OUTPUT_FILE_APPEND))
b7dd4d
+                return streq_ptr(context->stdio_file[STDOUT_FILENO], context->stdio_file[STDERR_FILENO]);
b7dd4d
+
b7dd4d
+        return true;
b7dd4d
+}
b7dd4d
+
b7dd4d
 static int setup_output(
b7dd4d
                 const Unit *unit,
b7dd4d
                 const ExecContext *context,
b7dd4d
@@ -603,7 +627,7 @@ static int setup_output(
b7dd4d
                         return fileno;
b7dd4d
 
b7dd4d
                 /* Duplicate from stdout if possible */
b7dd4d
-                if ((e == o && e != EXEC_OUTPUT_NAMED_FD) || e == EXEC_OUTPUT_INHERIT)
b7dd4d
+                if (can_inherit_stderr_from_stdout(context, o, e))
b7dd4d
                         return dup2(STDOUT_FILENO, fileno) < 0 ? -errno : fileno;
b7dd4d
 
b7dd4d
                 o = e;
b7dd4d
@@ -694,7 +718,6 @@ static int setup_output(
b7dd4d
                         flags |= O_APPEND;
b7dd4d
 
b7dd4d
                 fd = acquire_path(context->stdio_file[fileno], flags, 0666 & ~context->umask);
b7dd4d
-
b7dd4d
                 if (fd < 0)
b7dd4d
                         return fd;
b7dd4d