summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
authorLuca Boccassi <bluca@debian.org>2023-04-20 12:55:06 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2023-04-25 17:19:57 +0200
commit4a75704b166de533cedf8f9fab16ffae77bf2093 (patch)
tree7d45a062b040811fd2de10e121d9a654096ea178 /src/shared
parentb4e5c103be9de99dfb5e2e47fd1563cf5388978a (diff)
downloadsystemd-4a75704b166de533cedf8f9fab16ffae77bf2093.tar.gz
pam: do not attempt to close sd-bus after fork in pam_end()
When pam_end() is called after a fork, and it cleans up caches, it sets PAM_DATA_SILENT in error_status. FDs will be shared with the parent, so we do not want to attempt to close them from a child process, or we'll hit assertions. Complain loudly and skip.
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/pam-util.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/shared/pam-util.c b/src/shared/pam-util.c
index bf576c482e..4d864af717 100644
--- a/src/shared/pam-util.c
+++ b/src/shared/pam-util.c
@@ -50,6 +50,17 @@ int pam_syslog_pam_error(pam_handle_t *handle, int level, int error, const char
}
static void cleanup_system_bus(pam_handle_t *handle, void *data, int error_status) {
+ /* The PAM_DATA_SILENT flag is the way that pam_end() communicates to the module stack that this
+ * invocation of pam_end() is not the final one, but in the process that is going to directly exec
+ * the child. This means we are being called after a fork(), and we do not want to try and clean
+ * up the sd-bus object, as it would affect the parent too and we'll hit an assertion. */
+ if (error_status & PAM_DATA_SILENT)
+ return (void) pam_syslog_pam_error(
+ handle,
+ LOG_ERR,
+ SYNTHETIC_ERRNO(EUCLEAN),
+ "Attempted to close sd-bus after fork, this should not happen.");
+
sd_bus_flush_close_unref(data);
}