summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Schmidt <mschmidt@redhat.com>2011-11-16 23:45:01 +0100
committerMichal Schmidt <mschmidt@redhat.com>2011-11-16 23:52:10 +0100
commit4d8a7798e7f12c6400495cbc4d0ad57ed20ce90a (patch)
tree53dd18d58fd8d78aa2a18f3a7b026abc9bbbaacc
parent085c98af4eb17858b4687068f12eccc51a032732 (diff)
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.
-rw-r--r--src/execute.c1
-rw-r--r--src/log.c4
-rw-r--r--src/log.h1
3 files changed, 6 insertions, 0 deletions
diff --git a/src/execute.c b/src/execute.c
index 250d53a424..065101431d 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 b8ce122f3d..5c5b734f2f 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 c402afb8ea..9942e3e9a0 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);