[gnome-initial-setup: 1/20] timezone: Fix use-after-free race



commit c35bed6d7976c8c1a9a179fb440b5bb573c6c89d
Author: Philip Withnall <withnall endlessm com>
Date:   Wed Feb 5 16:18:57 2020 +0000

    timezone: Fix use-after-free race
    
    If the page is destroyed while the D-Bus call to set the timezone is
    still pending, a use-after-free will happen when that call completes.
    Typically, the page is destroyed early if the locale is changed.
    
    Avoid that by cancelling the call if the page is destroyed beforehand.
    
    Signed-off-by: Philip Withnall <withnall endlessm com>

 .../pages/timezone/gis-timezone-page.c             | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)
---
diff --git a/gnome-initial-setup/pages/timezone/gis-timezone-page.c 
b/gnome-initial-setup/pages/timezone/gis-timezone-page.c
index 7bf4e90..ca1088e 100644
--- a/gnome-initial-setup/pages/timezone/gis-timezone-page.c
+++ b/gnome-initial-setup/pages/timezone/gis-timezone-page.c
@@ -71,6 +71,7 @@ struct _GisTimezonePagePrivate
   gboolean in_geoclue_callback;
   GWeatherLocation *current_location;
   Timedate1 *dtm;
+  GCancellable *dtm_cancellable;
 
   GnomeWallClock *clock;
   GDesktopClockFormat clock_format;
@@ -87,17 +88,14 @@ set_timezone_cb (GObject      *source,
                  GAsyncResult *res,
                  gpointer      user_data)
 {
-  GisTimezonePage *page = user_data;
-  GisTimezonePagePrivate *priv = gis_timezone_page_get_instance_private (page);
-  GError *error;
+  Timedate1 *dtm = TIMEDATE1 (source);
+  g_autoptr(GError) error = NULL;
 
-  error = NULL;
-  if (!timedate1_call_set_timezone_finish (priv->dtm,
+  if (!timedate1_call_set_timezone_finish (dtm,
                                            res,
                                            &error)) {
     /* TODO: display any error in a user friendly way */
     g_warning ("Could not set system timezone: %s", error->message);
-    g_error_free (error);
   }
 }
 
@@ -112,7 +110,7 @@ queue_set_timezone (GisTimezonePage *page,
   timedate1_call_set_timezone (priv->dtm,
                                tzid,
                                TRUE,
-                               NULL,
+                               priv->dtm_cancellable,
                                set_timezone_cb,
                                page);
 }
@@ -399,12 +397,14 @@ gis_timezone_page_constructed (GObject *object)
 
   G_OBJECT_CLASS (gis_timezone_page_parent_class)->constructed (object);
 
+  priv->dtm_cancellable = g_cancellable_new ();
+
   error = NULL;
   priv->dtm = timedate1_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
                                                 G_DBUS_PROXY_FLAGS_NONE,
                                                 "org.freedesktop.timedate1",
                                                 "/org/freedesktop/timedate1",
-                                                NULL,
+                                                priv->dtm_cancellable,
                                                 &error);
   if (priv->dtm == NULL) {
     g_error ("Failed to create proxy for timedated: %s", error->message);
@@ -444,6 +444,12 @@ gis_timezone_page_dispose (GObject *object)
 
   stop_geolocation (page);
 
+  if (priv->dtm_cancellable != NULL)
+    {
+      g_cancellable_cancel (priv->dtm_cancellable);
+      g_clear_object (&priv->dtm_cancellable);
+    }
+
   g_clear_object (&priv->dtm);
   g_clear_object (&priv->clock);
 


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