]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pam_systemd_home: always close already opened bus connection in open_session() 31403/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 21 Feb 2024 04:21:31 +0000 (13:21 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 21 Feb 2024 04:22:54 +0000 (13:22 +0900)
Fixes #31375.

src/home/pam_systemd_home.c
src/shared/pam-util.c
src/shared/pam-util.h

index 4904516724d1cf6f7766a31a7954811c2e680c4b..077f9208cb5ab2d062da825e79c115f1d35f42ac 100644 (file)
@@ -826,6 +826,12 @@ _public_ PAM_EXTERN int pam_sm_open_session(
         if (r != PAM_SUCCESS)
                 return r;
 
+        /* Explicitly get saved PamBusData here. Otherwise, this function may succeed without setting 'd'
+         * even if there is an opened sd-bus connection, and it will be leaked. See issue #31375. */
+        r = pam_get_bus_data(handle, "pam-systemd-home", &d);
+        if (r != PAM_SUCCESS)
+                return r;
+
         r = acquire_home(handle, flags, debug, &d);
         if (r == PAM_USER_UNKNOWN) /* Not managed by us? Don't complain. */
                 return PAM_SUCCESS;
index c93ab9afebea0950ed9f69349d97ef2886913202..e3d92038aa8ddaf2885b37c69dbeaa4b074ad9d9 100644 (file)
@@ -209,6 +209,32 @@ int pam_release_bus_connection(pam_handle_t *handle, const char *module_name) {
         return PAM_SUCCESS;
 }
 
+int pam_get_bus_data(
+                pam_handle_t *handle,
+                const char *module_name,
+                PamBusData **ret) {
+
+        PamBusData *d = NULL;
+        _cleanup_free_ char *cache_id = NULL;
+        int r;
+
+        assert(handle);
+        assert(module_name);
+        assert(ret);
+
+        cache_id = pam_make_bus_cache_id(module_name);
+        if (!cache_id)
+                return pam_log_oom(handle);
+
+        /* We cache the bus connection so that we can share it between the session and the authentication hooks */
+        r = pam_get_data(handle, cache_id, (const void**) &d);
+        if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
+                return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get bus connection: @PAMERR@");
+
+        *ret = d;
+        return PAM_SUCCESS;
+}
+
 void pam_cleanup_free(pam_handle_t *handle, void *data, int error_status) {
         /* A generic destructor for pam_set_data() that just frees the specified data */
         free(data);
index 3439d4246e1636edb6064ac281e0c03869e8f43e..51bffc329e56afb5b7302ab9c2e28b544f4b0efe 100644 (file)
@@ -37,6 +37,7 @@ void pam_bus_data_disconnectp(PamBusData **d);
  * helps avoid a clash in the internal data structures of sd-bus. It will be used as key for cache items. */
 int pam_acquire_bus_connection(pam_handle_t *handle, const char *module_name, sd_bus **ret_bus, PamBusData **ret_bus_data);
 int pam_release_bus_connection(pam_handle_t *handle, const char *module_name);
+int pam_get_bus_data(pam_handle_t *handle, const char *module_name, PamBusData **ret);
 
 void pam_cleanup_free(pam_handle_t *handle, void *data, int error_status);