- Add patchset to fix gvariant parsing issues. (bsc#1111499). 0001-gvariant-Fix-checking-arithmetic-for-tuple-element-e.patch 0002-gvarianttype-Impose-a-recursion-limit-of-64-on-varia.patch 0003-gvariant-Check-array-offsets-against-serialised-data.patch 0004-gvariant-Check-tuple-offsets-against-serialised-data.patch 0005-gvariant-Limit-GVariant-strings-to-G_MAXSSIZE.patch 0006-gdbusmessage-Validate-type-of-message-header-signatu.patch 0007-gdbusmessage-Improve-documentation-for-g_dbus_messag.patch 0008-gdbusmessage-Clarify-error-returns-for-g_dbus_messag.patch 0009-gdbusmessage-Fix-a-typo-in-a-documentation-comment.patch 0010-gdbusmessage-Check-for-valid-GVariantType-when-parsi.patch 0011-gvariant-Clarify-internal-documentation-about-GVaria.patch 0012-tests-Tidy-up-GError-handling-in-gdbus-serialization.patch 0013-tests-Use-g_assert_null-in-gdbus-serialization-test.patch 0014-gutf8-Add-a-g_utf8_validate_len-function.patch 0015-glib-Port-various-callers-to-use-g_utf8_validate_len.patch OBS-URL: https://build.opensuse.org/request/show/644162 OBS-URL: https://build.opensuse.org/package/show/GNOME:Factory/glib2?expand=0&rev=370
145 lines
5.3 KiB
Diff
145 lines
5.3 KiB
Diff
From bef07b9c22e2f2127ae2c7cb5ac9a6568be39509 Mon Sep 17 00:00:00 2001
|
||
From: Philip Withnall <withnall@endlessm.com>
|
||
Date: Thu, 16 Aug 2018 21:33:52 +0100
|
||
Subject: [PATCH 06/15] gdbusmessage: Validate type of message header signature
|
||
field
|
||
MIME-Version: 1.0
|
||
Content-Type: text/plain; charset=UTF-8
|
||
Content-Transfer-Encoding: 8bit
|
||
|
||
Parsing a D-Bus message with the signature field in the message header
|
||
of type other than ‘g’ (GVariant type signature) would cause a critical
|
||
warning. Instead, we should return a runtime error.
|
||
|
||
Includes a test.
|
||
|
||
oss-fuzz#9825
|
||
|
||
Signed-off-by: Philip Withnall <withnall@endlessm.com>
|
||
---
|
||
gio/gdbusmessage.c | 19 ++++++++++++++
|
||
gio/tests/gdbus-serialization.c | 56 +++++++++++++++++++++++++++++++++++++++++
|
||
2 files changed, 75 insertions(+)
|
||
|
||
diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c
|
||
index 8de836bf6..79bc11c16 100644
|
||
--- a/gio/gdbusmessage.c
|
||
+++ b/gio/gdbusmessage.c
|
||
@@ -2115,6 +2115,15 @@ g_dbus_message_new_from_blob (guchar *blob,
|
||
const gchar *signature_str;
|
||
gsize signature_str_len;
|
||
|
||
+ if (!g_variant_is_of_type (signature, G_VARIANT_TYPE_SIGNATURE))
|
||
+ {
|
||
+ g_set_error_literal (error,
|
||
+ G_IO_ERROR,
|
||
+ G_IO_ERROR_INVALID_ARGUMENT,
|
||
+ _("Signature header found but is not of type signature"));
|
||
+ goto out;
|
||
+ }
|
||
+
|
||
signature_str = g_variant_get_string (signature, &signature_str_len);
|
||
|
||
/* signature but no body */
|
||
@@ -2695,6 +2704,16 @@ g_dbus_message_to_blob (GDBusMessage *message,
|
||
body_start_offset = mbuf.valid_len;
|
||
|
||
signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
|
||
+
|
||
+ if (signature != NULL && !g_variant_is_of_type (signature, G_VARIANT_TYPE_SIGNATURE))
|
||
+ {
|
||
+ g_set_error_literal (error,
|
||
+ G_IO_ERROR,
|
||
+ G_IO_ERROR_INVALID_ARGUMENT,
|
||
+ _("Signature header found but is not of type signature"));
|
||
+ goto out;
|
||
+ }
|
||
+
|
||
signature_str = NULL;
|
||
if (signature != NULL)
|
||
signature_str = g_variant_get_string (signature, NULL);
|
||
diff --git a/gio/tests/gdbus-serialization.c b/gio/tests/gdbus-serialization.c
|
||
index 2ab856c48..3cdade6d7 100644
|
||
--- a/gio/tests/gdbus-serialization.c
|
||
+++ b/gio/tests/gdbus-serialization.c
|
||
@@ -873,6 +873,20 @@ message_serialize_header_checks (void)
|
||
g_assert (blob == NULL);
|
||
g_object_unref (message);
|
||
|
||
+ /*
|
||
+ * check that we can't serialize messages with SIGNATURE set to a non-signature-typed value
|
||
+ */
|
||
+ message = g_dbus_message_new_signal ("/the/path", "The.Interface", "TheMember");
|
||
+ g_dbus_message_set_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, g_variant_new_boolean (FALSE));
|
||
+ blob = g_dbus_message_to_blob (message, &blob_size, G_DBUS_CAPABILITY_FLAGS_NONE, &error);
|
||
+
|
||
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
|
||
+ g_assert_cmpstr (error->message, ==, "Signature header found but is not of type signature");
|
||
+ g_assert_null (blob);
|
||
+
|
||
+ g_clear_error (&error);
|
||
+ g_clear_object (&message);
|
||
+
|
||
/*
|
||
* check we can't serialize signal messages with INTERFACE, PATH or MEMBER unset / set to reserved value
|
||
*/
|
||
@@ -1083,6 +1097,46 @@ test_double_array (void)
|
||
|
||
/* ---------------------------------------------------------------------------------------------------- */
|
||
|
||
+/* Test that an invalid header in a D-Bus message (specifically, with a type
|
||
+ * which doesn’t match what’s expected for the given header) is gracefully
|
||
+ * handled with an error rather than a crash.
|
||
+ * The set of bytes here come directly from fuzzer output. */
|
||
+static void
|
||
+test_message_parse_non_signature_header (void)
|
||
+{
|
||
+ const guint8 data[] = {
|
||
+ 0x6c, /* byte order */
|
||
+ 0x04, /* message type */
|
||
+ 0x0f, /* message flags */
|
||
+ 0x01, /* major protocol version */
|
||
+ 0x00, 0x00, 0x00, 0x00, /* body length */
|
||
+ 0x00, 0x00, 0x00, 0xbc, /* message serial */
|
||
+ /* a{yv} of header fields:
|
||
+ * (things start to be invalid below here) */
|
||
+ 0x02, 0x00, 0x00, 0x00, /* array length (in bytes) */
|
||
+ G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE, /* array key */
|
||
+ /* GVariant array value: */
|
||
+ 0x04, /* signature length */
|
||
+ 'd', 0x00, 0x00, 'F', /* signature (invalid) */
|
||
+ 0x00, /* nul terminator */
|
||
+ /* (GVariant array value payload missing) */
|
||
+ /* (message body length missing) */
|
||
+ };
|
||
+ gsize size = sizeof (data);
|
||
+ GDBusMessage *message = NULL;
|
||
+ GError *local_error = NULL;
|
||
+
|
||
+ 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_null (message);
|
||
+
|
||
+ g_clear_error (&local_error);
|
||
+}
|
||
+
|
||
+/* ---------------------------------------------------------------------------------------------------- */
|
||
+
|
||
int
|
||
main (int argc,
|
||
char *argv[])
|
||
@@ -1102,6 +1156,8 @@ main (int argc,
|
||
message_parse_empty_arrays_of_arrays);
|
||
|
||
g_test_add_func ("/gdbus/message-serialize/double-array", test_double_array);
|
||
+ g_test_add_func ("/gdbus/message-parse/non-signature-header",
|
||
+ test_message_parse_non_signature_header);
|
||
|
||
return g_test_run();
|
||
}
|
||
--
|
||
2.14.4
|
||
|