Blob Blame History Raw
From 838ad64f4f4502f370dcbf5faaed94b618bdac08 Mon Sep 17 00:00:00 2001
From: Michal Schmidt <mschmidt@redhat.com>
Date: Wed, 16 Nov 2011 23:45:01 +0100
Subject: [PATCH] execute: avoid logging to closed fds

Several functions called from the "sd(EXEC)" process try to log messages
when all the file descriptors are already closed, including the logging
ones. The logging functions do not expect their fds to be closed and
they hit an assertion failure. The failure wants to be logged too,
so there is an infinite recursion, ended by a SIGSEGV.

When we close all fds, we must let log.c know about it.
(cherry picked from commit 4d8a7798e7f12c6400495cbc4d0ad57ed20ce90a)
---
 src/execute.c |    1 +
 src/log.c     |    4 ++++
 src/log.h     |    1 +
 3 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/src/execute.c b/src/execute.c
index 250d53a..0651014 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -1016,6 +1016,7 @@ int exec_spawn(ExecCommand *command,
                 /* Close sockets very early to make sure we don't
                  * block init reexecution because it cannot bind its
                  * sockets */
+                log_forget_fds();
                 if (close_all_fds(socket_fd >= 0 ? &socket_fd : fds,
                                   socket_fd >= 0 ? 1 : n_fds) < 0) {
                         r = EXIT_FDS;
diff --git a/src/log.c b/src/log.c
index b8ce122..5c5b734 100644
--- a/src/log.c
+++ b/src/log.c
@@ -237,6 +237,10 @@ void log_close(void) {
         log_close_syslog();
 }
 
+void log_forget_fds(void) {
+        console_fd = kmsg_fd = syslog_fd = -1;
+}
+
 void log_set_max_level(int level) {
         assert((level & LOG_PRIMASK) == level);
 
diff --git a/src/log.h b/src/log.h
index c402afb..9942e3e 100644
--- a/src/log.h
+++ b/src/log.h
@@ -57,6 +57,7 @@ int log_get_max_level(void);
 
 int log_open(void);
 void log_close(void);
+void log_forget_fds(void);
 
 void log_close_syslog(void);
 void log_close_kmsg(void);
-- 
1.7.7.5