From: Franck Bui Date: Mon, 19 Jan 2026 17:24:12 +0000 (+0100) Subject: pam_systemd: fix regression introduced in v258 by preserving the FIFO fd X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=49f7149947e963a94d15c51e4505d2ddd24b872d;p=thirdparty%2Fsystemd.git pam_systemd: fix regression introduced in v258 by preserving the FIFO fd Upstream commit 3180c4d introduced a version incompatibility between pam_systemd.so v258 and logind v257. This is problematic because such version mismatches can occur in practice: logind still cannot be restarted during a systemd package upgrade (it's a long-standing limitation, see https://github.com/systemd/systemd/issues/17308). When pam_systemd requests a new session, logind v257 returns a FIFO fd. pam_systemd.so v258 ignores this fd and closes it. logind interprets the closure as the session leader exiting and immediately terminates the session. This patch partially reverts commit 3180c4d and restores the handling of the FIFO fd in pam_systemd. The change is limited to the D-Bus APIs, since the varlink API was only introduced in logind v258. Follow-up for 3180c4d46151673a9c985e60f205d4c76a81573f. --- diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index 5ae3313eb89..ceda12ad4fd 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -10,6 +10,7 @@ #include #include "sd-bus.h" +#include "sd-daemon.h" #include "sd-varlink.h" #include "alloc-util.h" @@ -1254,19 +1255,35 @@ static int register_session( return PAM_SESSION_ERR; } + int session_fd; r = sd_bus_message_read( reply, "soshusub", &id, &object_path, &runtime_path, - /* session_fd= */ NULL, + &session_fd, &original_uid, &real_seat, &real_vtnr, &existing); if (r < 0) return pam_bus_log_parse_error(pamh, r); + + /* Since v258, logind fully relies on pidfd to monitor the lifetime of the session leader + * process and returns a dummy session_fd (no longer a fifo). However because logind cannot + * be restarted (known long-standing issue), we must still be prepared to receive a fifo fd + * from a running logind older than v258. */ + if (sd_is_fifo(session_fd, NULL) > 0) { + _cleanup_close_ int fd = fcntl(session_fd, F_DUPFD_CLOEXEC, 3); + if (fd < 0) + return pam_syslog_errno(pamh, LOG_ERR, errno, "Failed to dup session fd: %m"); + + r = pam_set_data(pamh, "systemd.session-fd", FD_TO_PTR(fd), NULL); + if (r != PAM_SUCCESS) + return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to install session fd: @PAMERR@"); + TAKE_FD(fd); + } } pam_debug_syslog(pamh, debug,