From 2890d17f26c73a2e9e4a9635d353388fde82151d Mon Sep 17 00:00:00 2001
From: Luca Boccassi <bluca@debian.org>
Date: Fri, 16 Jun 2023 22:31:04 +0100
Subject: [PATCH] journal: avoid infinite recursion when closing bad journal FD

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.

(cherry picked from commit 40cdb3b756abbeb66091b8e9f1a3d38308456828)
(cherry picked from commit 228bfcf041e89f09c798af864a93543f9d43ec05)
(cherry picked from commit f62c831ba704119194ecd6aabaaee0ecb8edf559)

Conflict:NA
Reference:https://github.com/systemd/systemd-stable/commit/2890d17f26c73a2e9e4a9635d353388fde82151d
---
 src/basic/log.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/basic/log.c b/src/basic/log.c
index 02e37ed6ce..ef44aea948 100644
--- a/src/basic/log.c
+++ b/src/basic/log.c
@@ -83,7 +83,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) {
@@ -107,7 +108,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) {
@@ -124,7 +126,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) {
@@ -196,7 +199,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) {
-- 
2.33.0

