Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP4:GA
glib2.36447
glib2-gdbusmessage-cache-arg0.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File glib2-gdbusmessage-cache-arg0.patch of Package glib2.36447
From 952852081db408259d5a546927f08e40d94701eb Mon Sep 17 00:00:00 2001 From: Philip Withnall <pwithnall@gnome.org> Date: Tue, 28 Nov 2023 12:58:20 +0000 Subject: [PATCH 01/17] gdbusmessage: Cache the arg0 value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Technically we can’t rely on it being kept alive by the `message->body` pointer, unless we can guarantee that the `GVariant` is always serialised. That’s not necessarily the case, so keep a separate ref on the arg0 value at all times. This avoids a potential use-after-free. Spotted by Thomas Haller in https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3720#note_1924707. [This is a prerequisite for having tests pass after fixing the vulnerability described in glib#3268, because after fixing that vulnerability, the use-after-free genuinely does happen during regression testing. -smcv] Signed-off-by: Philip Withnall <pwithnall@gnome.org> Helps: #3183, #3268 (cherry picked from commit 10e9a917be7fb92b6b27837ef7a7f1d0be6095d5) --- gio/gdbusmessage.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff -urp glib-2.62.6.orig/gio/gdbusmessage.c glib-2.62.6/gio/gdbusmessage.c --- glib-2.62.6.orig/gio/gdbusmessage.c 2020-03-18 08:16:11.000000000 -0500 +++ glib-2.62.6/gio/gdbusmessage.c 2024-08-19 15:05:42.806527740 -0500 @@ -471,6 +471,7 @@ struct _GDBusMessage guint32 serial; GHashTable *headers; GVariant *body; + GVariant *arg0_cache; /* (nullable) (owned) */ #ifdef G_OS_UNIX GUnixFDList *fd_list; #endif @@ -493,6 +494,7 @@ g_dbus_message_finalize (GObject *object g_hash_table_unref (message->headers); if (message->body != NULL) g_variant_unref (message->body); + g_clear_pointer (&message->arg0_cache, g_variant_unref); #ifdef G_OS_UNIX if (message->fd_list != NULL) g_object_unref (message->fd_list); @@ -1128,6 +1130,7 @@ g_dbus_message_set_body (GDBusMessage * if (body == NULL) { message->body = NULL; + message->arg0_cache = NULL; g_dbus_message_set_signature (message, NULL); } else @@ -1138,6 +1141,12 @@ g_dbus_message_set_body (GDBusMessage * message->body = g_variant_ref_sink (body); + if (g_variant_is_of_type (message->body, G_VARIANT_TYPE_TUPLE) && + g_variant_n_children (message->body) > 0) + message->arg0_cache = g_variant_get_child_value (message->body, 0); + else + message->arg0_cache = NULL; + type_string = g_variant_get_type_string (body); type_string_len = strlen (type_string); g_assert (type_string_len >= 2); @@ -2219,6 +2228,14 @@ g_dbus_message_new_from_blob (guchar 2, error); g_variant_type_free (variant_type); + + if (message->body != NULL && + g_variant_is_of_type (message->body, G_VARIANT_TYPE_TUPLE) && + g_variant_n_children (message->body) > 0) + message->arg0_cache = g_variant_get_child_value (message->body, 0); + else + message->arg0_cache = NULL; + if (message->body == NULL) goto out; } @@ -3254,22 +3271,13 @@ g_dbus_message_set_signature (GDBusMessa const gchar * g_dbus_message_get_arg0 (GDBusMessage *message) { - const gchar *ret; - g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL); - ret = NULL; + if (message->arg0_cache != NULL && + g_variant_is_of_type (message->arg0_cache, G_VARIANT_TYPE_STRING)) + return g_variant_get_string (message->arg0_cache, NULL); - if (message->body != NULL && g_variant_is_of_type (message->body, G_VARIANT_TYPE_TUPLE)) - { - GVariant *item; - item = g_variant_get_child_value (message->body, 0); - if (g_variant_is_of_type (item, G_VARIANT_TYPE_STRING)) - ret = g_variant_get_string (item, NULL); - g_variant_unref (item); - } - - return ret; + return NULL; } /* ---------------------------------------------------------------------------------------------------- */ @@ -3712,6 +3720,7 @@ g_dbus_message_copy (GDBusMessage *mess * to just ref (as opposed to deep-copying) the GVariant instances */ ret->body = message->body != NULL ? g_variant_ref (message->body) : NULL; + ret->arg0_cache = message->arg0_cache != NULL ? g_variant_ref (message->arg0_cache) : NULL; g_hash_table_iter_init (&iter, message->headers); while (g_hash_table_iter_next (&iter, &header_key, (gpointer) &header_value)) g_hash_table_insert (ret->headers, header_key, g_variant_ref (header_value));
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor