glib2.0/debian/patches/CVE-2024-34397-10.patch

166 lines
6.9 KiB
Diff

From: Simon McVittie <smcv@collabora.com>
Date: Tue, 23 Apr 2024 20:39:05 +0100
Subject: [PATCH 10/16] gdbusconnection: Stop storing sender_unique_name in
SignalData
This will become confusing when we start tracking the owner of a
well-known-name sender, and it's redundant anyway. Instead, track the
1 bit of data that we actually need: whether it's a well-known name.
Strictly speaking this too is redundant, because it's syntactically
derivable from the sender, but only via extra string operations.
A subsequent commit will add a data structure to keep track of the
owner of a well-known-name sender, at which point this boolean will
be replaced by the presence or absence of that data structure.
Signed-off-by: Simon McVittie <smcv@collabora.com>
---
gio/gdbusconnection.c | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index 278e9ca..761b5e5 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -327,19 +327,19 @@ typedef struct
{
gchar *rule;
gchar *sender;
- gchar *sender_unique_name; /* if sender is unique or org.freedesktop.DBus, then that name... otherwise blank */
gchar *interface_name;
gchar *member;
gchar *object_path;
gchar *arg0;
GDBusSignalFlags flags;
GPtrArray *subscribers; /* (owned) (element-type SignalSubscriber) */
+ gboolean sender_is_its_own_owner;
} SignalData;
static SignalData *
signal_data_new_take (gchar *rule,
gchar *sender,
- gchar *sender_unique_name,
+ gboolean sender_is_its_own_owner,
gchar *interface_name,
gchar *member,
gchar *object_path,
@@ -350,7 +350,7 @@ signal_data_new_take (gchar *rule,
signal_data->rule = rule;
signal_data->sender = sender;
- signal_data->sender_unique_name = sender_unique_name;
+ signal_data->sender_is_its_own_owner = sender_is_its_own_owner;
signal_data->interface_name = interface_name;
signal_data->member = member;
signal_data->object_path = object_path;
@@ -365,7 +365,6 @@ signal_data_free (SignalData *signal_data)
{
g_free (signal_data->rule);
g_free (signal_data->sender);
- g_free (signal_data->sender_unique_name);
g_free (signal_data->interface_name);
g_free (signal_data->member);
g_free (signal_data->object_path);
@@ -3447,7 +3446,7 @@ remove_match_rule (GDBusConnection *connection,
static gboolean
is_signal_data_for_name_lost_or_acquired (SignalData *signal_data)
{
- return g_strcmp0 (signal_data->sender_unique_name, "org.freedesktop.DBus") == 0 &&
+ return g_strcmp0 (signal_data->sender, "org.freedesktop.DBus") == 0 &&
g_strcmp0 (signal_data->interface_name, "org.freedesktop.DBus") == 0 &&
g_strcmp0 (signal_data->object_path, "/org/freedesktop/DBus") == 0 &&
(g_strcmp0 (signal_data->member, "NameLost") == 0 ||
@@ -3459,7 +3458,8 @@ is_signal_data_for_name_lost_or_acquired (SignalData *signal_data)
/* called in any thread, connection lock is held */
static void
add_signal_data (GDBusConnection *connection,
- SignalData *signal_data)
+ SignalData *signal_data,
+ const char *sender_unique_name)
{
GPtrArray *signal_data_array;
@@ -3479,12 +3479,12 @@ add_signal_data (GDBusConnection *connection,
}
signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array,
- signal_data->sender_unique_name);
+ sender_unique_name);
if (signal_data_array == NULL)
{
signal_data_array = g_ptr_array_new ();
g_hash_table_insert (connection->map_sender_unique_name_to_signal_data_array,
- g_strdup (signal_data->sender_unique_name),
+ g_strdup (sender_unique_name),
signal_data_array);
}
g_ptr_array_add (signal_data_array, signal_data);
@@ -3581,6 +3581,7 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection,
gchar *rule;
SignalData *signal_data;
SignalSubscriber *subscriber;
+ gboolean sender_is_its_own_owner;
const gchar *sender_unique_name;
/* Right now we abort if AddMatch() fails since it can only fail with the bus being in
@@ -3616,6 +3617,11 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection,
rule = args_to_rule (sender, interface_name, member, object_path, arg0, flags);
if (sender != NULL && (g_dbus_is_unique_name (sender) || g_strcmp0 (sender, "org.freedesktop.DBus") == 0))
+ sender_is_its_own_owner = TRUE;
+ else
+ sender_is_its_own_owner = FALSE;
+
+ if (sender_is_its_own_owner)
sender_unique_name = sender;
else
sender_unique_name = "";
@@ -3639,14 +3645,14 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection,
signal_data = signal_data_new_take (g_steal_pointer (&rule),
g_strdup (sender),
- g_strdup (sender_unique_name),
+ sender_is_its_own_owner,
g_strdup (interface_name),
g_strdup (member),
g_strdup (object_path),
g_strdup (arg0),
flags);
g_ptr_array_add (signal_data->subscribers, subscriber);
- add_signal_data (connection, signal_data);
+ add_signal_data (connection, signal_data, sender_unique_name);
out:
g_hash_table_insert (connection->map_id_to_signal_data,
@@ -3670,22 +3676,28 @@ static void
remove_signal_data_if_unused (GDBusConnection *connection,
SignalData *signal_data)
{
+ const gchar *sender_unique_name;
GPtrArray *signal_data_array;
if (signal_data->subscribers->len != 0)
return;
+ if (signal_data->sender_is_its_own_owner)
+ sender_unique_name = signal_data->sender;
+ else
+ sender_unique_name = "";
+
g_warn_if_fail (g_hash_table_remove (connection->map_rule_to_signal_data, signal_data->rule));
signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array,
- signal_data->sender_unique_name);
+ sender_unique_name);
g_warn_if_fail (signal_data_array != NULL);
g_warn_if_fail (g_ptr_array_remove (signal_data_array, signal_data));
if (signal_data_array->len == 0)
{
g_warn_if_fail (g_hash_table_remove (connection->map_sender_unique_name_to_signal_data_array,
- signal_data->sender_unique_name));
+ sender_unique_name));
}
/* remove the match rule from the bus unless NameLost or NameAcquired (see subscribe()) */