dryang / rpms / systemd

Forked from rpms/systemd a year ago
Clone
dd65c9
From 5a7f49bb38bc1d7965d497e775b7cc8053b0c465 Mon Sep 17 00:00:00 2001
dd65c9
From: Jan Synacek <jsynacek@redhat.com>
dd65c9
Date: Fri, 18 Aug 2017 10:17:22 +0200
dd65c9
Subject: [PATCH] log: never log into foreign fd #2 in PID 1 or its
dd65c9
 pre-execve() children
dd65c9
dd65c9
(cherry picked from commit 48a601fe5de8aa0d89ba6dadde168769fa7ce992)
dd65c9
Resolves: #1420505
dd65c9
---
dd65c9
 src/core/main.c  | 11 +++++++++--
dd65c9
 src/shared/log.c |  7 ++++++-
dd65c9
 src/shared/log.h |  1 +
dd65c9
 3 files changed, 16 insertions(+), 3 deletions(-)
dd65c9
dd65c9
diff --git a/src/core/main.c b/src/core/main.c
c62b8e
index 37e3ea0ced..66393ed6ad 100644
dd65c9
--- a/src/core/main.c
dd65c9
+++ b/src/core/main.c
dd65c9
@@ -1310,10 +1310,17 @@ int main(int argc, char *argv[]) {
dd65c9
         log_show_color(isatty(STDERR_FILENO) > 0);
dd65c9
         log_set_upgrade_syslog_to_journal(true);
dd65c9
 
dd65c9
-        /* Disable the umask logic */
dd65c9
-        if (getpid() == 1)
dd65c9
+        if (getpid() == 1) {
dd65c9
+                /* Disable the umask logic */
dd65c9
                 umask(0);
dd65c9
 
dd65c9
+                /* Always reopen /dev/console when running as PID 1 or one of its pre-execve() children. This is
dd65c9
+                 * important so that we never end up logging to any foreign stderr, for example if we have to log in a
dd65c9
+                 * child process right before execve()'ing the actual binary, at a point in time where socket
dd65c9
+                 * activation stderr/stdout area already set up. */
dd65c9
+                log_set_always_reopen_console(true);
dd65c9
+        }
dd65c9
+
dd65c9
         if (getpid() == 1 && detect_container(NULL) <= 0) {
dd65c9
 
dd65c9
                 /* Running outside of a container as PID 1 */
dd65c9
diff --git a/src/shared/log.c b/src/shared/log.c
c62b8e
index 646a1d6389..3491420308 100644
dd65c9
--- a/src/shared/log.c
dd65c9
+++ b/src/shared/log.c
dd65c9
@@ -52,6 +52,7 @@ static bool show_color = false;
dd65c9
 static bool show_location = false;
dd65c9
 
dd65c9
 static bool upgrade_syslog_to_journal = false;
dd65c9
+static bool always_reopen_console = false;
dd65c9
 
dd65c9
 /* Akin to glibc's __abort_msg; which is private and we hence cannot
dd65c9
  * use here. */
dd65c9
@@ -75,7 +76,7 @@ static int log_open_console(void) {
dd65c9
         if (console_fd >= 0)
dd65c9
                 return 0;
dd65c9
 
dd65c9
-        if (getpid() == 1) {
dd65c9
+        if (always_reopen_console) {
dd65c9
                 console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
dd65c9
                 if (console_fd < 0)
dd65c9
                         return console_fd;
dd65c9
@@ -1061,3 +1062,7 @@ void log_received_signal(int level, const struct signalfd_siginfo *si) {
dd65c9
 void log_set_upgrade_syslog_to_journal(bool b) {
dd65c9
         upgrade_syslog_to_journal = b;
dd65c9
 }
dd65c9
+
dd65c9
+void log_set_always_reopen_console(bool b) {
dd65c9
+        always_reopen_console = b;
dd65c9
+}
dd65c9
diff --git a/src/shared/log.h b/src/shared/log.h
c62b8e
index 2889e1e77f..3c9448f1a7 100644
dd65c9
--- a/src/shared/log.h
dd65c9
+++ b/src/shared/log.h
dd65c9
@@ -210,3 +210,4 @@ LogTarget log_target_from_string(const char *s) _pure_;
dd65c9
 void log_received_signal(int level, const struct signalfd_siginfo *si);
dd65c9
 
dd65c9
 void log_set_upgrade_syslog_to_journal(bool b);
dd65c9
+void log_set_always_reopen_console(bool b);