From 6499ad53567a64cb70f2fdc690ad405350fe1ce3 Mon Sep 17 00:00:00 2001 From: Sebastian Wilhelmi Date: Thu, 6 Jan 2022 21:04:56 +0000 Subject: [PATCH] gdbusmessage: Disallow empty structures/tuples in D-Bus messages They are disallowed in the specification: https://dbus.freedesktop.org/doc/dbus-specification.html#container-types Helps: #2557 --- gio/gdbusmessage.c | 19 +++++++ gio/tests/gdbus-serialization.c | 88 +++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c index cc8f37e5d..4056bc2c4 100644 --- a/gio/gdbusmessage.c +++ b/gio/gdbusmessage.c @@ -1907,6 +1907,16 @@ parse_value_from_blob (GMemoryBuffer *buf, g_variant_builder_init (&builder, type); element_type = g_variant_type_first (type); + if (!element_type) + { + g_variant_builder_clear (&builder); + g_set_error_literal (&local_error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Empty structures (tuples) are not allowed in D-Bus")); + goto fail; + } + while (element_type != NULL) { GVariant *item; @@ -2617,6 +2627,15 @@ append_value_to_blob (GVariant *value, default: if (g_variant_type_is_dict_entry (type) || g_variant_type_is_tuple (type)) { + if (!g_variant_type_first (type)) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Empty structures (tuples) are not allowed in D-Bus")); + goto fail; + } + padding_added = ensure_output_padding (mbuf, 8); if (value != NULL) { diff --git a/gio/tests/gdbus-serialization.c b/gio/tests/gdbus-serialization.c index 4f0634cf1..7cc46a4ae 100644 --- a/gio/tests/gdbus-serialization.c +++ b/gio/tests/gdbus-serialization.c @@ -1529,6 +1529,90 @@ test_message_parse_truncated (void) g_free (blob); } +static void +test_message_parse_empty_structure (void) +{ + const guint8 data[] = + { + 'l', /* little-endian byte order */ + 0x02, /* message type (method return) */ + 0x00, /* message flags (none) */ + 0x01, /* major protocol version */ + 0x08, 0x00, 0x00, 0x00, /* body length (in bytes) */ + 0x00, 0x00, 0x00, 0x00, /* message serial */ + /* a{yv} of header fields */ + 0x20, 0x00, 0x00, 0x00, /* array length (in bytes), must be a multiple of 8 */ + 0x01, /* array key (PATH) */ + 0x01, /* signature length */ + 'o', /* type (OBJECT_PATH) */ + 0x00, /* nul terminator */ + 0x05, 0x00, 0x00, 0x00, /* length 5 */ + '/', 'p', 'a', 't', 'h', 0x00, 0x00, 0x00, /* string '/path' and padding */ + 0x03, /* array key (MEMBER) */ + 0x01, /* signature length */ + 's', /* type (STRING) */ + 0x00, /* nul terminator */ + 0x06, 0x00, 0x00, 0x00, /* length 6 */ + 'M', 'e', 'm', 'b', 'e', 'r', 0x00, 0x00, /* string 'Member' and padding */ + 0x08, /* array key (SIGNATURE) */ + 0x01, /* signature length */ + 'g', /* type (SIGNATURE) */ + 0x00, /* nul terminator */ + 0x03, /* length 3 */ + 'a', '(', ')', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* type 'a()' and padding */ + 0x08, 0x00, 0x00, 0x00, /* array length: 4 bytes */ + 0x00, 0x00, 0x00, 0x00, /* padding to 8 bytes */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* array data */ + 0x00 + }; + gsize size = sizeof (data); + GDBusMessage *message = NULL; + GError *local_error = NULL; + + g_test_summary ("Test that empty structures are rejected when parsing."); + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2557"); + + message = g_dbus_message_new_from_blob ((guchar *) data, size, + G_DBUS_CAPABILITY_FLAGS_NONE, + &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (local_error->message, ==, "Empty structures (tuples) are not allowed in D-Bus"); + g_assert_null (message); + + g_clear_error (&local_error); +} + +static void +test_message_serialize_empty_structure (void) +{ + GDBusMessage *message; + GVariantBuilder builder; + gsize size = 0; + GError *local_error = NULL; + + g_test_summary ("Test that empty structures are rejected when serializing."); + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2557"); + + message = g_dbus_message_new (); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(a())")); + g_variant_builder_open (&builder, G_VARIANT_TYPE ("a()")); + g_variant_builder_add (&builder, "()"); + g_variant_builder_close (&builder); + g_dbus_message_set_message_type (message, G_DBUS_MESSAGE_TYPE_METHOD_CALL); + g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_PATH, + g_variant_new_object_path ("/path")); + g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_MEMBER, + g_variant_new_string ("Member")); + g_dbus_message_set_body (message, g_variant_builder_end (&builder)); + + g_dbus_message_to_blob (message, &size, G_DBUS_CAPABILITY_FLAGS_NONE, &local_error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_assert_cmpstr (local_error->message, ==, "Empty structures (tuples) are not allowed in D-Bus"); + + g_clear_error (&local_error); + g_clear_object (&message); +} + /* ---------------------------------------------------------------------------------------------------- */ int @@ -1550,6 +1634,8 @@ main (int argc, test_message_serialize_header_checks); g_test_add_func ("/gdbus/message-serialize/double-array", test_message_serialize_double_array); + g_test_add_func ("/gdbus/message-serialize/empty-structure", + test_message_serialize_empty_structure); g_test_add_func ("/gdbus/message-parse/empty-arrays-of-arrays", test_message_parse_empty_arrays_of_arrays); @@ -1567,6 +1653,8 @@ main (int argc, test_message_parse_deep_body_nesting); g_test_add_func ("/gdbus/message-parse/truncated", test_message_parse_truncated); + g_test_add_func ("/gdbus/message-parse/empty-structure", + test_message_parse_empty_structure); return g_test_run(); }