mirror of https://gitee.com/openkylin/glib2.0.git
68 lines
3.0 KiB
Diff
68 lines
3.0 KiB
Diff
From: Simon McVittie <smcv@collabora.com>
|
|
Date: Thu, 14 Mar 2024 20:42:41 +0000
|
|
Subject: [PATCH 12/16] gdbusconnection: Don't deliver signals if the sender
|
|
doesn't match
|
|
|
|
Otherwise a malicious connection on a shared bus, especially the system
|
|
bus, could trick GDBus clients into processing signals sent by the
|
|
malicious connection as though they had come from the real owner of a
|
|
well-known service name.
|
|
|
|
Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/3268
|
|
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
|
---
|
|
gio/gdbusconnection.c | 40 ++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 40 insertions(+)
|
|
|
|
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
|
|
index a0ebe37..e707716 100644
|
|
--- a/gio/gdbusconnection.c
|
|
+++ b/gio/gdbusconnection.c
|
|
@@ -4299,6 +4299,46 @@ schedule_callbacks (GDBusConnection *connection,
|
|
if (signal_data->object_path != NULL && g_strcmp0 (signal_data->object_path, path) != 0)
|
|
continue;
|
|
|
|
+ if (signal_data->shared_name_watcher != NULL)
|
|
+ {
|
|
+ /* We want signals from a specified well-known name, which means
|
|
+ * the signal's sender needs to be the unique name that currently
|
|
+ * owns that well-known name, and we will have found this
|
|
+ * SignalData in
|
|
+ * connection->map_sender_unique_name_to_signal_data_array[""]. */
|
|
+ const WatchedName *watched_name;
|
|
+ const char *current_owner;
|
|
+
|
|
+ g_assert (signal_data->sender != NULL);
|
|
+ /* Invariant: We never need to watch for the owner of a unique
|
|
+ * name, or for the owner of DBUS_SERVICE_DBUS, either of which
|
|
+ * is always its own owner */
|
|
+ g_assert (!g_dbus_is_unique_name (signal_data->sender));
|
|
+ g_assert (g_strcmp0 (signal_data->sender, DBUS_SERVICE_DBUS) != 0);
|
|
+
|
|
+ watched_name = signal_data->shared_name_watcher->watched_name;
|
|
+ g_assert (watched_name != NULL);
|
|
+ current_owner = watched_name->owner;
|
|
+
|
|
+ /* Skip the signal if the actual sender is not known to own
|
|
+ * the required name */
|
|
+ if (current_owner == NULL || g_strcmp0 (current_owner, sender) != 0)
|
|
+ continue;
|
|
+ }
|
|
+ else if (signal_data->sender != NULL)
|
|
+ {
|
|
+ /* We want signals from a unique name or o.fd.DBus... */
|
|
+ g_assert (g_dbus_is_unique_name (signal_data->sender)
|
|
+ || g_str_equal (signal_data->sender, DBUS_SERVICE_DBUS));
|
|
+
|
|
+ /* ... which means we must have found this SignalData in
|
|
+ * connection->map_sender_unique_name_to_signal_data_array[signal_data->sender],
|
|
+ * therefore we would only have found it if the signal's
|
|
+ * actual sender matches the required signal_data->sender */
|
|
+ g_assert (g_strcmp0 (signal_data->sender, sender) == 0);
|
|
+ }
|
|
+ /* else the sender is unspecified and we will accept anything */
|
|
+
|
|
if (signal_data->arg0 != NULL)
|
|
{
|
|
if (signal_data->flags & G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE)
|