chiark / gitweb /
execute: avoid logging to closed fds
authorMichal Schmidt <mschmidt@redhat.com>
Wed, 16 Nov 2011 22:45:01 +0000 (23:45 +0100)
committerMichal Schmidt <mschmidt@redhat.com>
Wed, 16 Nov 2011 22:52:10 +0000 (23:52 +0100)
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.

src/execute.c
src/log.c
src/log.h

index 250d53a424a07655929439929a62a56d6eec99c0..065101431d10fa987d81fbbb0625ce45fa0c3c36 100644 (file)
@@ -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 */
                 /* 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;
                 if (close_all_fds(socket_fd >= 0 ? &socket_fd : fds,
                                   socket_fd >= 0 ? 1 : n_fds) < 0) {
                         r = EXIT_FDS;
index b8ce122f3d338bead2af6c904899f4fa9568fcad..5c5b734f2f83c96a9bf7cb18cfdf89e630dbea0e 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -237,6 +237,10 @@ void log_close(void) {
         log_close_syslog();
 }
 
         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);
 
 void log_set_max_level(int level) {
         assert((level & LOG_PRIMASK) == level);
 
index c402afb8ea48eff08d0307679ffe4c9c35cd97df..9942e3e9a05a21ea3dfca659080e2c1faf51d6bd 100644 (file)
--- 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);
 
 int log_open(void);
 void log_close(void);
+void log_forget_fds(void);
 
 void log_close_syslog(void);
 void log_close_kmsg(void);
 
 void log_close_syslog(void);
 void log_close_kmsg(void);