Blame SOURCES/0001-manager-Don-t-leak-session-objects.patch

230af0
From 7d4eed356eb8a9a87f49d49405ab506271178968 Mon Sep 17 00:00:00 2001
230af0
From: Ray Strode <rstrode@redhat.com>
230af0
Date: Mon, 14 Sep 2020 16:20:09 -0400
230af0
Subject: [PATCH 1/3] manager: Don't leak session objects
230af0
230af0
The first is from create_user_session_for display.  Most callers don't
230af0
check the return value, so it should just be void.
230af0
230af0
The user data associated with the session also isn't unlinked from the
230af0
display when the display is finishing up, preventing the display and
230af0
session object from getting freed.
230af0
230af0
This commit makes both changes.
230af0
---
230af0
 daemon/gdm-manager.c | 17 +++++++++--------
230af0
 1 file changed, 9 insertions(+), 8 deletions(-)
230af0
230af0
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
230af0
index 66f814a6e..8f9be10ef 100644
230af0
--- a/daemon/gdm-manager.c
230af0
+++ b/daemon/gdm-manager.c
230af0
@@ -94,63 +94,63 @@ struct GdmManagerPrivate
230af0
 #ifdef  WITH_PLYMOUTH
230af0
         guint                     plymouth_is_running : 1;
230af0
 #endif
230af0
         guint                     ran_once : 1;
230af0
 };
230af0
 
230af0
 enum {
230af0
         PROP_0,
230af0
         PROP_XDMCP_ENABLED,
230af0
         PROP_SHOW_LOCAL_GREETER
230af0
 };
230af0
 
230af0
 enum {
230af0
         DISPLAY_ADDED,
230af0
         DISPLAY_REMOVED,
230af0
         LAST_SIGNAL
230af0
 };
230af0
 
230af0
 typedef enum {
230af0
         SESSION_RECORD_LOGIN,
230af0
         SESSION_RECORD_LOGOUT,
230af0
         SESSION_RECORD_FAILED,
230af0
 } SessionRecord;
230af0
 
230af0
 static guint signals [LAST_SIGNAL] = { 0, };
230af0
 
230af0
 static void     gdm_manager_class_init  (GdmManagerClass *klass);
230af0
 static void     gdm_manager_init        (GdmManager      *manager);
230af0
 static void     gdm_manager_dispose     (GObject         *object);
230af0
 
230af0
-static GdmSession *create_user_session_for_display (GdmManager *manager,
230af0
-                                                    GdmDisplay *display,
230af0
-                                                    uid_t       allowed_user);
230af0
+static void     create_user_session_for_display (GdmManager *manager,
230af0
+                                                 GdmDisplay *display,
230af0
+                                                 uid_t       allowed_user);
230af0
 static void     start_user_session (GdmManager                *manager,
230af0
                                     StartUserSessionOperation *operation);
230af0
 static void     clean_user_session (GdmSession *session);
230af0
 
230af0
 static gpointer manager_object = NULL;
230af0
 
230af0
 static void manager_interface_init (GdmDBusManagerIface *interface);
230af0
 
230af0
 G_DEFINE_TYPE_WITH_CODE (GdmManager,
230af0
                          gdm_manager,
230af0
                          GDM_DBUS_TYPE_MANAGER_SKELETON,
230af0
                          G_IMPLEMENT_INTERFACE (GDM_DBUS_TYPE_MANAGER,
230af0
                                                 manager_interface_init));
230af0
 
230af0
 #ifdef WITH_PLYMOUTH
230af0
 static gboolean
230af0
 plymouth_is_running (void)
230af0
 {
230af0
         int      status;
230af0
         gboolean res;
230af0
         GError  *error;
230af0
 
230af0
         error = NULL;
230af0
         res = g_spawn_command_line_sync ("/bin/plymouth --ping",
230af0
                                          NULL, NULL, &status, &error);
230af0
         if (! res) {
230af0
                 g_debug ("Could not ping plymouth: %s", error->message);
230af0
                 g_error_free (error);
230af0
                 return FALSE;
230af0
         }
230af0
@@ -1466,61 +1466,62 @@ out:
230af0
 }
230af0
 
230af0
 static const char *
230af0
 get_username_for_greeter_display (GdmManager *manager,
230af0
                                   GdmDisplay *display)
230af0
 {
230af0
         gboolean doing_initial_setup = FALSE;
230af0
 
230af0
         g_object_get (G_OBJECT (display),
230af0
                       "doing-initial-setup", &doing_initial_setup,
230af0
                       NULL);
230af0
 
230af0
         if (doing_initial_setup) {
230af0
                 return INITIAL_SETUP_USERNAME;
230af0
         } else {
230af0
                 return GDM_USERNAME;
230af0
         }
230af0
 }
230af0
 
230af0
 static void
230af0
 set_up_automatic_login_session (GdmManager *manager,
230af0
                                 GdmDisplay *display)
230af0
 {
230af0
         GdmSession *session;
230af0
         char       *display_session_type = NULL;
230af0
         gboolean is_initial;
230af0
 
230af0
         /* 0 is root user; since the daemon talks to the session object
230af0
          * directly, itself, for automatic login
230af0
          */
230af0
-        session = create_user_session_for_display (manager, display, 0);
230af0
+        create_user_session_for_display (manager, display, 0);
230af0
+        session = get_user_session_for_display (display);
230af0
 
230af0
         g_object_get (G_OBJECT (display),
230af0
                       "is-initial", &is_initial,
230af0
                       "session-type", &display_session_type,
230af0
                       NULL);
230af0
 
230af0
         g_object_set (G_OBJECT (session),
230af0
                       "display-is-initial", is_initial,
230af0
                       NULL);
230af0
 
230af0
         g_debug ("GdmManager: Starting automatic login conversation");
230af0
         gdm_session_start_conversation (session, "gdm-autologin");
230af0
 }
230af0
 
230af0
 static void
230af0
 set_up_chooser_session (GdmManager *manager,
230af0
                         GdmDisplay *display)
230af0
 {
230af0
         const char *allowed_user;
230af0
         struct passwd *passwd_entry;
230af0
 
230af0
         allowed_user = get_username_for_greeter_display (manager, display);
230af0
 
230af0
         if (!gdm_get_pwent_for_name (allowed_user, &passwd_entry)) {
230af0
                 g_warning ("GdmManager: couldn't look up username %s",
230af0
                            allowed_user);
230af0
                 gdm_display_unmanage (display);
230af0
                 gdm_display_finish (display);
230af0
                 return;
230af0
         }
230af0
@@ -1682,60 +1683,62 @@ on_display_status_changed (GdmDisplay *display,
230af0
 
230af0
         switch (status) {
230af0
                 case GDM_DISPLAY_PREPARED:
230af0
                 case GDM_DISPLAY_MANAGED:
230af0
                         if ((display_number == -1 && status == GDM_DISPLAY_PREPARED) ||
230af0
                             (display_number != -1 && status == GDM_DISPLAY_MANAGED)) {
230af0
                                 char *session_class;
230af0
 
230af0
                                 g_object_get (display,
230af0
                                               "session-class", &session_class,
230af0
                                               NULL);
230af0
                                 if (g_strcmp0 (session_class, "greeter") == 0)
230af0
                                         set_up_session (manager, display);
230af0
                                 g_free (session_class);
230af0
                         }
230af0
 
230af0
                         if (status == GDM_DISPLAY_MANAGED) {
230af0
                                 greeter_display_started (manager, display);
230af0
                         }
230af0
                         break;
230af0
                 case GDM_DISPLAY_FAILED:
230af0
                 case GDM_DISPLAY_UNMANAGED:
230af0
                 case GDM_DISPLAY_FINISHED:
230af0
 #ifdef WITH_PLYMOUTH
230af0
                         if (quit_plymouth) {
230af0
                                 plymouth_quit_without_transition ();
230af0
                                 manager->priv->plymouth_is_running = FALSE;
230af0
                         }
230af0
 #endif
230af0
 
230af0
+                        g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL);
230af0
+
230af0
                         if (status == GDM_DISPLAY_FINISHED || g_strcmp0 (session_type, "x11") == 0) {
230af0
                                 manager->priv->ran_once = TRUE;
230af0
                         }
230af0
                         maybe_start_pending_initial_login (manager, display);
230af0
                         break;
230af0
                 default:
230af0
                         break;
230af0
         }
230af0
 
230af0
 }
230af0
 
230af0
 static void
230af0
 on_display_removed (GdmDisplayStore *display_store,
230af0
                     const char      *id,
230af0
                     GdmManager      *manager)
230af0
 {
230af0
         GdmDisplay *display;
230af0
 
230af0
         display = gdm_display_store_lookup (display_store, id);
230af0
         if (display != NULL) {
230af0
                 g_dbus_object_manager_server_unexport (manager->priv->object_manager, id);
230af0
 
230af0
                 g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), manager);
230af0
 
230af0
                 g_signal_emit (manager, signals[DISPLAY_REMOVED], 0, id);
230af0
         }
230af0
 }
230af0
 
230af0
 static void
230af0
 destroy_start_user_session_operation (StartUserSessionOperation *operation)
230af0
@@ -2331,61 +2334,61 @@ on_session_reauthentication_started (GdmSession *session,
230af0
                                      int         pid_of_caller,
230af0
                                      const char *address,
230af0
                                      GdmManager *manager)
230af0
 {
230af0
         GDBusMethodInvocation *invocation;
230af0
         gpointer               source_tag;
230af0
 
230af0
         g_debug ("GdmManager: reauthentication started");
230af0
 
230af0
         source_tag = GINT_TO_POINTER (pid_of_caller);
230af0
 
230af0
         invocation = g_hash_table_lookup (manager->priv->open_reauthentication_requests,
230af0
                                           source_tag);
230af0
 
230af0
         if (invocation != NULL) {
230af0
                 g_hash_table_steal (manager->priv->open_reauthentication_requests,
230af0
                                     source_tag);
230af0
                 gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager),
230af0
                                                                          invocation,
230af0
                                                                          address);
230af0
         }
230af0
 }
230af0
 
230af0
 static void
230af0
 clean_user_session (GdmSession *session)
230af0
 {
230af0
         g_object_set_data (G_OBJECT (session), "gdm-display", NULL);
230af0
         g_object_unref (session);
230af0
 }
230af0
 
230af0
-static GdmSession *
230af0
+static void
230af0
 create_user_session_for_display (GdmManager *manager,
230af0
                                  GdmDisplay *display,
230af0
                                  uid_t       allowed_user)
230af0
 {
230af0
         GdmSession *session;
230af0
         gboolean    display_is_local = FALSE;
230af0
         char       *display_name = NULL;
230af0
         char       *display_device = NULL;
230af0
         char       *remote_hostname = NULL;
230af0
         char       *display_auth_file = NULL;
230af0
         char       *display_seat_id = NULL;
230af0
         char       *display_id = NULL;
230af0
 #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
230af0
         char       *display_session_type = NULL;
230af0
         gboolean    greeter_is_wayland;
230af0
 #endif
230af0
 
230af0
         g_object_get (G_OBJECT (display),
230af0
                       "id", &display_id,
230af0
                       "x11-display-name", &display_name,
230af0
                       "is-local", &display_is_local,
230af0
                       "remote-hostname", &remote_hostname,
230af0
                       "x11-authority-file", &display_auth_file,
230af0
                       "seat-id", &display_seat_id,
230af0
 #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
230af0
                       "session-type", &display_session_type,
230af0
 #endif
230af0
                       NULL);
230af0
         display_device = get_display_device (manager, display);
230af0
 
230af0
@@ -2441,70 +2444,68 @@ create_user_session_for_display (GdmManager *manager,
230af0
                           "conversation-stopped",
230af0
                           G_CALLBACK (on_session_conversation_stopped),
230af0
                           manager);
230af0
         g_signal_connect (session,
230af0
                           "authentication-failed",
230af0
                           G_CALLBACK (on_session_authentication_failed),
230af0
                           manager);
230af0
         g_signal_connect (session,
230af0
                           "session-opened",
230af0
                           G_CALLBACK (on_user_session_opened),
230af0
                           manager);
230af0
         g_signal_connect (session,
230af0
                           "session-started",
230af0
                           G_CALLBACK (on_user_session_started),
230af0
                           manager);
230af0
         g_signal_connect (session,
230af0
                           "session-start-failed",
230af0
                           G_CALLBACK (on_session_start_failed),
230af0
                           manager);
230af0
         g_signal_connect (session,
230af0
                           "session-exited",
230af0
                           G_CALLBACK (on_user_session_exited),
230af0
                           manager);
230af0
         g_signal_connect (session,
230af0
                           "session-died",
230af0
                           G_CALLBACK (on_user_session_died),
230af0
                           manager);
230af0
         g_object_set_data (G_OBJECT (session), "gdm-display", display);
230af0
         g_object_set_data_full (G_OBJECT (display),
230af0
                                 "gdm-user-session",
230af0
-                                g_object_ref (session),
230af0
+                                session,
230af0
                                 (GDestroyNotify)
230af0
                                 clean_user_session);
230af0
 
230af0
 #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
230af0
         greeter_is_wayland = g_strcmp0 (display_session_type, "wayland") == 0;
230af0
         g_object_set (G_OBJECT (session), "ignore-wayland", !greeter_is_wayland, NULL);
230af0
 #endif
230af0
-
230af0
-        return session;
230af0
 }
230af0
 
230af0
 static void
230af0
 on_display_added (GdmDisplayStore *display_store,
230af0
                   const char      *id,
230af0
                   GdmManager      *manager)
230af0
 {
230af0
         GdmDisplay *display;
230af0
 
230af0
         display = gdm_display_store_lookup (display_store, id);
230af0
 
230af0
         if (display != NULL) {
230af0
                 g_dbus_object_manager_server_export (manager->priv->object_manager,
230af0
                                                      gdm_display_get_object_skeleton (display));
230af0
 
230af0
                 g_signal_connect (display, "notify::status",
230af0
                                   G_CALLBACK (on_display_status_changed),
230af0
                                   manager);
230af0
                 g_signal_emit (manager, signals[DISPLAY_ADDED], 0, id);
230af0
         }
230af0
 }
230af0
 
230af0
 GQuark
230af0
 gdm_manager_error_quark (void)
230af0
 {
230af0
         static GQuark ret = 0;
230af0
         if (ret == 0) {
230af0
                 ret = g_quark_from_static_string ("gdm_manager_error");
230af0
         }
230af0
 
230af0
-- 
230af0
2.26.2
230af0