[gnome-software/1128-possible-thread-race-condition] GsApp: Fix possible thread race condition around 'launchable' property
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/1128-possible-thread-race-condition] GsApp: Fix possible thread race condition around 'launchable' property
- Date: Fri, 26 Mar 2021 10:09:04 +0000 (UTC)
commit d0eb5be26a6d68abefce08c698801ef653c0b961
Author: Milan Crha <mcrha redhat com>
Date: Fri Mar 26 11:06:20 2021 +0100
GsApp: Fix possible thread race condition around 'launchable' property
The 'launchable' property can change due to change notifications
after install/uninstall of the application, which can cause use-after-free
in the functions, which read the property.
Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1128
lib/gs-app.c | 28 +++++++++++++++++++++++++++-
lib/gs-app.h | 3 +++
lib/gs-plugin.c | 6 +++---
src/gs-details-page.c | 6 +++---
4 files changed, 36 insertions(+), 7 deletions(-)
---
diff --git a/lib/gs-app.c b/lib/gs-app.c
index 12ee9a292..4f9f773a3 100644
--- a/lib/gs-app.c
+++ b/lib/gs-app.c
@@ -2547,11 +2547,14 @@ gs_app_set_url_missing (GsApp *app, const gchar *url)
* @app: a #GsApp
* @kind: a #AsLaunchableKind, e.g. %AS_LAUNCHABLE_KIND_DESKTOP_ID
*
- * Gets a launchable of a specific type.
+ * Gets a launchable of a specific type. Note, this function is not thread safe,
+ * use gs_app_dup_launchable() instead.
*
* Returns: a string, or %NULL for unset
*
* Since: 40
+ *
+ * Deprecated: 41: Use gs_app_dup_launchable() instead.
**/
const gchar *
gs_app_get_launchable (GsApp *app, AsLaunchableKind kind)
@@ -2562,6 +2565,29 @@ gs_app_get_launchable (GsApp *app, AsLaunchableKind kind)
as_launchable_kind_to_string (kind));
}
+/**
+ * gs_app_dup_launchable:
+ * @app: a #GsApp
+ * @kind: a #AsLaunchableKind, e.g. %AS_LAUNCHABLE_KIND_DESKTOP_ID
+ *
+ * Gets a launchable of a specific type as a newly allocated string.
+ * Free it with g_free(), when no longer needed.
+ *
+ * Returns: (transfer full) (nullable): a newly allocated string, or %NULL when unset
+ *
+ * Since: 41
+ **/
+gchar *
+gs_app_dup_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_strdup (g_hash_table_lookup (priv->launchables,
+ as_launchable_kind_to_string (kind)));
+}
+
/**
* gs_app_set_launchable:
* @app: a #GsApp
diff --git a/lib/gs-app.h b/lib/gs-app.h
index 3136b639f..fe59134a0 100644
--- a/lib/gs-app.h
+++ b/lib/gs-app.h
@@ -312,8 +312,11 @@ void gs_app_set_url (GsApp *app,
const gchar *gs_app_get_url_missing (GsApp *app);
void gs_app_set_url_missing (GsApp *app,
const gchar *url);
+G_DEPRECATED_FOR(gs_app_dup_launchable)
const gchar *gs_app_get_launchable (GsApp *app,
AsLaunchableKind kind);
+gchar *gs_app_dup_launchable (GsApp *app,
+ AsLaunchableKind kind);
void gs_app_set_launchable (GsApp *app,
AsLaunchableKind kind,
const gchar *launchable);
diff --git a/lib/gs-plugin.c b/lib/gs-plugin.c
index b9a609150..0a387fac8 100644
--- a/lib/gs-plugin.c
+++ b/lib/gs-plugin.c
@@ -944,12 +944,12 @@ gs_plugin_app_launch_cb (gpointer user_data)
gboolean
gs_plugin_app_launch (GsPlugin *plugin, GsApp *app, GError **error)
{
- const gchar *desktop_id;
+ g_autofree gchar *desktop_id = NULL;
g_autoptr(GAppInfo) appinfo = NULL;
- desktop_id = gs_app_get_launchable (app, AS_LAUNCHABLE_KIND_DESKTOP_ID);
+ desktop_id = gs_app_dup_launchable (app, AS_LAUNCHABLE_KIND_DESKTOP_ID);
if (desktop_id == NULL)
- desktop_id = gs_app_get_id (app);
+ desktop_id = g_strdup (gs_app_get_id (app));
if (desktop_id == NULL) {
g_set_error (error,
GS_PLUGIN_ERROR,
diff --git a/src/gs-details-page.c b/src/gs-details-page.c
index 8723987b7..f0d6e3144 100644
--- a/src/gs-details-page.c
+++ b/src/gs-details-page.c
@@ -872,8 +872,8 @@ gs_details_page_get_alternates_cb (GObject *source_object,
static gboolean
gs_details_page_can_launch_app (GsDetailsPage *self)
{
- const gchar *desktop_id;
GDesktopAppInfo *desktop_appinfo;
+ g_autofree gchar *desktop_id = NULL;
g_autoptr(GAppInfo) appinfo = NULL;
if (!self->app)
@@ -892,9 +892,9 @@ gs_details_page_can_launch_app (GsDetailsPage *self)
gs_app_has_quirk (self->app, GS_APP_QUIRK_PARENTAL_NOT_LAUNCHABLE))
return FALSE;
- desktop_id = gs_app_get_launchable (self->app, AS_LAUNCHABLE_KIND_DESKTOP_ID);
+ desktop_id = gs_app_dup_launchable (self->app, AS_LAUNCHABLE_KIND_DESKTOP_ID);
if (!desktop_id)
- desktop_id = gs_app_get_id (self->app);
+ desktop_id = g_strdup (gs_app_get_id (self->app));
if (!desktop_id)
return FALSE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]