]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journal: avoid infinite recursion when closing bad journal FD
authorLuca Boccassi <bluca@debian.org>
Fri, 16 Jun 2023 21:31:04 +0000 (22:31 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Sun, 18 Jun 2023 11:31:53 +0000 (12:31 +0100)
When trying to log, if we fail we try to close the journal FD. If
it is bad, safe_close() will fail and assert, which will try to log,
which will fail, which will try to close the journal FD...
Infinite recursion looks very pretty live in gdb, but let's avoid
that by immediately invalidating the journal FD before closing it.

src/basic/log.c

index dc88b70d7577d28a8acc3f4453f294b74739c4ef..a41d4bcdb62b15d10142fddca5398f8b2562e574 100644 (file)
@@ -106,7 +106,8 @@ bool _log_message_dummy = false; /* Always false */
         } while (false)
 
 static void log_close_console(void) {
-        console_fd = safe_close_above_stdio(console_fd);
+        /* See comment in log_close_journal() */
+        (void) safe_close_above_stdio(TAKE_FD(console_fd));
 }
 
 static int log_open_console(void) {
@@ -130,7 +131,8 @@ static int log_open_console(void) {
 }
 
 static void log_close_kmsg(void) {
-        kmsg_fd = safe_close(kmsg_fd);
+        /* See comment in log_close_journal() */
+        (void) safe_close(TAKE_FD(kmsg_fd));
 }
 
 static int log_open_kmsg(void) {
@@ -147,7 +149,8 @@ static int log_open_kmsg(void) {
 }
 
 static void log_close_syslog(void) {
-        syslog_fd = safe_close(syslog_fd);
+        /* See comment in log_close_journal() */
+        (void) safe_close(TAKE_FD(syslog_fd));
 }
 
 static int create_log_socket(int type) {
@@ -212,7 +215,11 @@ fail:
 }
 
 static void log_close_journal(void) {
-        journal_fd = safe_close(journal_fd);
+        /* If the journal FD is bad, safe_close will fail, and will try to log, which will fail, so we'll
+         * try to close the journal FD, which is bad, so safe_close will fail... Whether we can close it
+         * or not, invalidate it immediately so that we don't get in a recursive loop until we run out of
+         * stack. */
+        (void) safe_close(TAKE_FD(journal_fd));
 }
 
 static int log_open_journal(void) {