From 05e5fc24b0f803098c1d05dae86f5eb05bd0c2a4 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Sun, 15 Nov 2015 14:07:53 -0500 Subject: session: Cancel worker proxy async ops when freeing conversations We need to cancel ongoing async ops for worker proxies when freeing conversations or we'll crash when the completion handler runs and we access free'd memory. https://bugzilla.gnome.org/show_bug.cgi?id=758032 --- daemon/gdm-session.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'daemon/gdm-session.c') diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c index 1eff3d18..99f3a014 100644 --- a/daemon/gdm-session.c +++ b/daemon/gdm-session.c @@ -73,6 +73,7 @@ typedef struct GDBusMethodInvocation *pending_invocation; GdmDBusWorkerManager *worker_manager_interface; GdmDBusWorker *worker_proxy; + GCancellable *worker_cancellable; char *session_id; guint32 is_stopping : 1; @@ -1043,6 +1044,8 @@ register_worker (GdmDBusWorkerManager *worker_manager_interface, g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (conversation->worker_proxy), G_MAXINT); + conversation->worker_cancellable = g_cancellable_new (); + g_signal_connect (conversation->worker_proxy, "username-changed", G_CALLBACK (worker_on_username_changed), conversation); @@ -1679,6 +1682,9 @@ free_conversation (GdmSessionConversation *conversation) g_free (conversation->session_id); g_clear_object (&conversation->worker_manager_interface); + g_cancellable_cancel (conversation->worker_cancellable); + g_clear_object (&conversation->worker_cancellable); + if (conversation->worker_proxy != NULL) { g_signal_handlers_disconnect_by_func (conversation->worker_proxy, G_CALLBACK (worker_on_username_changed), @@ -2123,7 +2129,7 @@ send_setup (GdmSession *self, display_hostname, self->priv->display_is_local, self->priv->display_is_initial, - NULL, + conversation->worker_cancellable, (GAsyncReadyCallback) on_setup_complete_cb, conversation); } @@ -2189,7 +2195,7 @@ send_setup_for_user (GdmSession *self, display_hostname, self->priv->display_is_local, self->priv->display_is_initial, - NULL, + conversation->worker_cancellable, (GAsyncReadyCallback) on_setup_complete_cb, conversation); } @@ -2251,7 +2257,7 @@ send_setup_for_program (GdmSession *self, self->priv->display_is_local, self->priv->display_is_initial, log_file, - NULL, + conversation->worker_cancellable, (GAsyncReadyCallback) on_setup_complete_cb, conversation); } @@ -2309,7 +2315,7 @@ gdm_session_authenticate (GdmSession *self, conversation = find_conversation_by_name (self, service_name); if (conversation != NULL) { gdm_dbus_worker_call_authenticate (conversation->worker_proxy, - NULL, + conversation->worker_cancellable, (GAsyncReadyCallback) on_authenticate_cb, conversation); } @@ -2326,7 +2332,7 @@ gdm_session_authorize (GdmSession *self, conversation = find_conversation_by_name (self, service_name); if (conversation != NULL) { gdm_dbus_worker_call_authorize (conversation->worker_proxy, - NULL, + conversation->worker_cancellable, (GAsyncReadyCallback) on_authorize_cb, conversation); } @@ -2343,7 +2349,7 @@ gdm_session_accredit (GdmSession *self, conversation = find_conversation_by_name (self, service_name); if (conversation != NULL) { gdm_dbus_worker_call_establish_credentials (conversation->worker_proxy, - NULL, + conversation->worker_cancellable, (GAsyncReadyCallback) on_establish_credentials_cb, conversation); } @@ -2357,7 +2363,8 @@ send_environment_variable (const char *key, { gdm_dbus_worker_call_set_environment_variable (conversation->worker_proxy, key, value, - NULL, NULL, NULL); + conversation->worker_cancellable, + NULL, NULL); } static void @@ -2547,7 +2554,8 @@ send_display_mode (GdmSession *self, mode = gdm_session_get_display_mode (self); gdm_dbus_worker_call_set_session_display_mode (conversation->worker_proxy, gdm_session_display_mode_to_string (mode), - NULL, NULL, NULL); + conversation->worker_cancellable, + NULL, NULL); } static void @@ -2563,7 +2571,8 @@ send_session_type (GdmSession *self, gdm_dbus_worker_call_set_environment_variable (conversation->worker_proxy, "XDG_SESSION_TYPE", session_type, - NULL, NULL, NULL); + conversation->worker_cancellable, + NULL, NULL); } void @@ -2581,7 +2590,7 @@ gdm_session_open_session (GdmSession *self, send_session_type (self, conversation); gdm_dbus_worker_call_open (conversation->worker_proxy, - NULL, + conversation->worker_cancellable, (GAsyncReadyCallback) on_opened, conversation); } } @@ -2767,7 +2776,7 @@ gdm_session_start_session (GdmSession *self, gdm_dbus_worker_call_start_program (conversation->worker_proxy, program, - NULL, + conversation->worker_cancellable, (GAsyncReadyCallback) on_start_program_cb, conversation); g_free (program); @@ -2899,7 +2908,7 @@ gdm_session_start_reauthentication (GdmSession *session, gdm_dbus_worker_call_start_reauthentication (conversation->worker_proxy, (int) pid_of_caller, (int) uid_of_caller, - NULL, + conversation->worker_cancellable, (GAsyncReadyCallback) on_reauthentication_started_cb, conversation); } @@ -3136,7 +3145,8 @@ gdm_session_select_session (GdmSession *self, gdm_dbus_worker_call_set_session_name (conversation->worker_proxy, get_session_name (self), - NULL, NULL, NULL); + conversation->worker_cancellable, + NULL, NULL); } } -- cgit v1.2.1