[gnome-initial-setup/shell/4765: 46/362] location: fix TimezoneMonitor use-after-free



commit 3a70636088f5db2ea44edde36104daeb26e419a4
Author: Daniel Drake <drake endlessm com>
Date:   Fri Jun 6 11:09:40 2014 +0100

    location: fix TimezoneMonitor use-after-free
    
    When a TimezoneMonitor is finalized, it triggers a GCancellable in
    attempt to cancel ongoing asynchronous geoclue operations, right before
    the TimezoneMonitor is freed.
    
    However, cancellation here is asynchronous, it is not processed until
    later. Two such callbacks here were attempting to access the
    TimezoneMonitor in question before verifying that the geoclue operation
    completed successfully (in event of finalization, the TimezoneMonitor is
    already freed).
    
    Do appropriate error checking in these callbacks before accessing
    the TimezoneMonitor and its private data.
    
    [endlessm/eos-shell#2560]

 .../pages/location/cc-timezone-monitor.c           |   14 ++++++++++----
 1 files changed, 10 insertions(+), 4 deletions(-)
---
diff --git a/gnome-initial-setup/pages/location/cc-timezone-monitor.c 
b/gnome-initial-setup/pages/location/cc-timezone-monitor.c
index 996063d..37e77f5 100644
--- a/gnome-initial-setup/pages/location/cc-timezone-monitor.c
+++ b/gnome-initial-setup/pages/location/cc-timezone-monitor.c
@@ -292,15 +292,18 @@ on_client_proxy_ready (GObject      *source_object,
 {
         GError *error = NULL;
         CcTimezoneMonitor *self = user_data;
-        CcTimezoneMonitorPrivate *priv = GET_PRIVATE (self);
+        GeoclueClient *client;
+        CcTimezoneMonitorPrivate *priv;
 
-        priv->geoclue_client = geoclue_client_proxy_new_for_bus_finish (res, &error);
+        client = geoclue_client_proxy_new_for_bus_finish (res, &error);
         if (error != NULL) {
                 g_critical ("Failed to connect to GeoClue2 service: %s", error->message);
                 g_error_free (error);
                 return;
         }
 
+        priv = GET_PRIVATE (self);
+        priv->geoclue_client = client;
         //geoclue_client_set_desktop_id (priv->geoclue_client, DESKTOP_ID);
         geoclue_client_set_distance_threshold (priv->geoclue_client,
                                                GEOCODE_LOCATION_ACCURACY_CITY);
@@ -352,15 +355,18 @@ on_manager_proxy_ready (GObject      *source_object,
 
         GError *error = NULL;
         CcTimezoneMonitor *self = user_data;
-        CcTimezoneMonitorPrivate *priv = GET_PRIVATE (self);
+        CcTimezoneMonitorPrivate *priv;
+        GeoclueManager *manager;
 
-        priv->geoclue_manager = geoclue_manager_proxy_new_for_bus_finish (res, &error);
+        manager = geoclue_manager_proxy_new_for_bus_finish (res, &error);
         if (error != NULL) {
                 g_critical ("Failed to connect to GeoClue2 service: %s", error->message);
                 g_error_free (error);
                 return;
         }
 
+        priv = GET_PRIVATE (self);
+        priv->geoclue_manager = manager;
         geoclue_manager_call_get_client (priv->geoclue_manager,
                                          priv->cancellable,
                                          on_get_client_ready,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]