]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pam_systemd: fix regression introduced in v258 by preserving the FIFO fd
authorFranck Bui <fbui@suse.com>
Mon, 19 Jan 2026 17:24:12 +0000 (18:24 +0100)
committerMike Yuan <me@yhndnzj.com>
Thu, 22 Jan 2026 18:13:13 +0000 (19:13 +0100)
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.

src/login/pam_systemd.c

index 5ae3313eb894cd3e6cb0e68070bf3d95fd715bf4..ceda12ad4fd1f3c35498cb55b1c65b0bb5bb2bd2 100644 (file)
@@ -10,6 +10,7 @@
 #include <unistd.h>
 
 #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,