From 05e5fc24b0f803098c1d05dae86f5eb05bd0c2a4 Mon Sep 17 00:00:00 2001 From: Rui Matos <tiagomatos@gmail.com> 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(-) diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c index 1eff3d1..99f3a01 100644 --- a/daemon/gdm-session.c +++ b/daemon/gdm-session.c @@ -71,6 +71,7 @@ typedef struct GDBusMethodInvocation *pending_invocation; GdmDBusWorkerManager *worker_manager_interface; GdmDBusWorker *worker_proxy; + GCancellable *worker_cancellable; char *session_id; guint32 is_stopping : 1; @@ -354,7 +355,8 @@ on_establish_credentials_cb (GdmDBusWork 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); gdm_session_open_session (self, service_name); break; default: @@ -1067,6 +1069,8 @@ register_worker (GdmDBusWorkerManager * 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); @@ -1700,6 +1704,9 @@ free_conversation (GdmSessionConversatio 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), @@ -2061,7 +2068,7 @@ send_setup (GdmSession *self, display_seat_id, display_hostname, self->priv->display_is_local, - NULL, + conversation->worker_cancellable, (GAsyncReadyCallback) on_setup_complete_cb, conversation); } @@ -2126,7 +2133,7 @@ send_setup_for_user (GdmSession *self, display_seat_id, display_hostname, self->priv->display_is_local, - NULL, + conversation->worker_cancellable, (GAsyncReadyCallback) on_setup_complete_cb, conversation); } @@ -2187,7 +2194,7 @@ send_setup_for_program (GdmSession *self display_hostname, self->priv->display_is_local, log_file, - NULL, + conversation->worker_cancellable, (GAsyncReadyCallback) on_setup_complete_cb, conversation); } @@ -2243,7 +2250,7 @@ gdm_session_authenticate (GdmSession *se 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); } @@ -2260,7 +2267,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); } @@ -2277,7 +2284,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); } @@ -2291,7 +2298,8 @@ send_environment_variable (const char { gdm_dbus_worker_call_set_environment_variable (conversation->worker_proxy, key, value, - NULL, NULL, NULL); + conversation->worker_cancellable, + NULL, NULL); } static void @@ -2481,7 +2489,7 @@ gdm_session_open_session (GdmSession *se if (conversation != NULL) { gdm_dbus_worker_call_open (conversation->worker_proxy, - NULL, + conversation->worker_cancellable, (GAsyncReadyCallback) on_opened, conversation); } } @@ -2620,7 +2628,7 @@ gdm_session_start_session (GdmSession *s gdm_dbus_worker_call_start_program (conversation->worker_proxy, program, - NULL, + conversation->worker_cancellable, (GAsyncReadyCallback) on_start_program_cb, conversation); g_free (program); @@ -2760,7 +2768,7 @@ gdm_session_start_reauthentication (GdmS 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); } @@ -2935,7 +2943,8 @@ gdm_session_select_session_type (GdmSess gdm_dbus_worker_call_set_session_type (conversation->worker_proxy, text, - NULL, NULL, NULL); + conversation->worker_cancellable, + NULL, NULL); } } @@ -2962,7 +2971,8 @@ gdm_session_select_session (GdmSession * gdm_dbus_worker_call_set_session_name (conversation->worker_proxy, get_session_name (self), - NULL, NULL, NULL); + conversation->worker_cancellable, + NULL, NULL); } }