[gnome-software/1128-possible-thread-race-condition] GsApp: Fix possible thread race condition around 'launchable' property




commit 66d1f9bd9232ad03407f1cc7cbde0aaa69c8acb7
Author: Milan Crha <mcrha redhat com>
Date:   Fri Mar 26 11:06:20 2021 +0100

    GsApp: Fix possible thread race condition around 'launchable' property
    
    Do not overwrite already set 'launchable' property values, to avoid use-after-free
    when other thread reads the value. The property is set and valid through
    the lifetime of the object. Also avoid unnecessary static memory duplication.
    
    Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1128

 lib/gs-app.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)
---
diff --git a/lib/gs-app.c b/lib/gs-app.c
index 12ee9a292..a04960f04 100644
--- a/lib/gs-app.c
+++ b/lib/gs-app.c
@@ -2557,7 +2557,9 @@ const gchar *
 gs_app_get_launchable (GsApp *app, AsLaunchableKind kind)
 {
        GsAppPrivate *priv = gs_app_get_instance_private (app);
+       g_autoptr(GMutexLocker) locker = NULL;
        g_return_val_if_fail (GS_IS_APP (app), NULL);
+       locker = g_mutex_locker_new (&priv->mutex);
        return g_hash_table_lookup (priv->launchables,
                                    as_launchable_kind_to_string (kind));
 }
@@ -2576,12 +2578,21 @@ void
 gs_app_set_launchable (GsApp *app, AsLaunchableKind kind, const gchar *launchable)
 {
        GsAppPrivate *priv = gs_app_get_instance_private (app);
+       gpointer current_value = NULL;
+       const gchar *key;
        g_autoptr(GMutexLocker) locker = NULL;
        g_return_if_fail (GS_IS_APP (app));
        locker = g_mutex_locker_new (&priv->mutex);
-       g_hash_table_insert (priv->launchables,
-                            g_strdup (as_launchable_kind_to_string (kind)),
-                            g_strdup (launchable));
+       key = as_launchable_kind_to_string (kind);
+       if (g_hash_table_lookup_extended (priv->launchables, key, NULL, &current_value)) {
+               if (g_strcmp0 ((const gchar *) current_value, launchable) != 0)
+                       g_warning ("Preventing app '%s' replace of %s's launchable '%s' with '%s'",
+                               priv->name, key, (const gchar *) current_value, launchable);
+       } else {
+               g_hash_table_insert (priv->launchables,
+                                    (gpointer) as_launchable_kind_to_string (kind),
+                                    g_strdup (launchable));
+       }
 }
 
 /**
@@ -5020,7 +5031,7 @@ gs_app_init (GsApp *app)
                                            g_free);
        priv->launchables = g_hash_table_new_full (g_str_hash,
                                                   g_str_equal,
-                                                  g_free,
+                                                  NULL,
                                                   g_free);
        priv->allow_cancel = TRUE;
        g_mutex_init (&priv->mutex);


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