From: Luca Boccassi Date: Thu, 20 Apr 2023 11:55:06 +0000 (+0100) Subject: pam: do not attempt to close sd-bus after fork in pam_end() X-Git-Tag: v254-rc1~637 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4a75704b166de533cedf8f9fab16ffae77bf2093;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/shared/pam-util.c b/src/shared/pam-util.c index bf576c482ef..4d864af7175 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); }