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