pam_systemd: fix regression introduced in v258 by preserving the FIFO fd
Upstream commit3180c4dintroduced 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 commit3180c4dand 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 for3180c4d461.
This commit is contained in:
+18
-1
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user