From 79f36b64159708cf2b261207f007fe980e6dfaa5 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Fri, 19 Jan 2024 19:57:31 +0800 Subject: [PATCH 1/2] pam_systemd: close pidfd after use --- src/login/pam_systemd.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index d7814a7275..b8313b92cc 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -802,13 +802,21 @@ typedef struct SessionContext { const char *runtime_max_sec; } SessionContext; -static int create_session_message(sd_bus *bus, pam_handle_t *handle, const SessionContext *context, bool avoid_pidfd, sd_bus_message **ret) { +static int create_session_message( + sd_bus *bus, + pam_handle_t *handle, + const SessionContext *context, + bool avoid_pidfd, + sd_bus_message **ret) { + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; - int r, pidfd = -EBADFD; + _cleanup_close_ int pidfd = -EBADF; + int r; assert(bus); assert(handle); assert(context); + assert(ret); if (!avoid_pidfd) { pidfd = pidfd_open(getpid_cached(), 0); @@ -1066,7 +1074,7 @@ _public_ PAM_EXTERN int pam_sm_open_session( r = create_session_message(bus, handle, &context, - false /* avoid_pidfd = */, + /* avoid_pidfd = */ false, &m); if (r < 0) return pam_bus_log_create_error(handle, r); From 2948803177bf5027c1808a9a55481c45dd91624c Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Fri, 19 Jan 2024 20:00:31 +0800 Subject: [PATCH 2/2] pam_systemd: always check if session is busy We need to check for BUS_ERROR_SESSION_BUSY no matter whether pidfd is used, i.e. after we retry with CreateSession(). --- src/login/pam_systemd.c | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index b8313b92cc..db623a3eaa 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -1080,33 +1080,33 @@ _public_ PAM_EXTERN int pam_sm_open_session( return pam_bus_log_create_error(handle, r); r = sd_bus_call(bus, m, LOGIN_SLOW_BUS_CALL_TIMEOUT_USEC, &error, &reply); + if (r < 0 && sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD)) { + sd_bus_error_free(&error); + pam_debug_syslog(handle, debug, + "CreateSessionWithPIDFD() API is not available, retrying with CreateSession()."); + + m = sd_bus_message_unref(m); + r = create_session_message(bus, + handle, + &context, + /* avoid_pidfd = */ true, + &m); + if (r < 0) + return pam_bus_log_create_error(handle, r); + + r = sd_bus_call(bus, m, LOGIN_SLOW_BUS_CALL_TIMEOUT_USEC, &error, &reply); + } if (r < 0) { if (sd_bus_error_has_name(&error, BUS_ERROR_SESSION_BUSY)) { + /* We are already in a session, don't do anything */ pam_debug_syslog(handle, debug, "Not creating session: %s", bus_error_message(&error, r)); - /* We are already in a session, don't do anything */ goto success; - } else if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD)) { - pam_debug_syslog(handle, debug, - "CreateSessionWithPIDFD() API is not available, retrying with CreateSession()."); - - m = sd_bus_message_unref(m); - r = create_session_message(bus, - handle, - &context, - true /* avoid_pidfd = */, - &m); - if (r < 0) - return pam_bus_log_create_error(handle, r); - - sd_bus_error_free(&error); - r = sd_bus_call(bus, m, LOGIN_SLOW_BUS_CALL_TIMEOUT_USEC, &error, &reply); - } - if (r < 0) { - pam_syslog(handle, LOG_ERR, - "Failed to create session: %s", bus_error_message(&error, r)); - return PAM_SESSION_ERR; } + + pam_syslog(handle, LOG_ERR, + "Failed to create session: %s", bus_error_message(&error, r)); + return PAM_SESSION_ERR; } r = sd_bus_message_read(reply,