glib2/gvariant-Fix-checking-arithmetic-for-tuple-element-e.patch
2019-09-30 10:40:42 -04:00

98 lines
3.2 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From eb7c9adc3b2570f6b82110b52a24609d124f38de Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Thu, 16 Aug 2018 20:12:02 +0100
Subject: [PATCH 160/682] gvariant: Fix checking arithmetic for tuple element
ends
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When checking whether a serialised GVariant tuple is in normal form,
its possible for `offset_ptr -= offset_size` to underflow and wrap
around, resulting in gvs_read_unaligned_le() reading memory outside the
serialised GVariant bounds.
See §(Tuples) in gvariant-serialiser.c for the documentation on how
tuples are serialised. Briefly, all variable-length elements in the
tuple have an offset to their end stored in an array of offsets at the
end of the tuple. The width of each offset is in offset_size. offset_ptr
is added to the start of the serialised tuple to get the offset which is
currently being examined. The offset array is in reverse order compared
to the tuple elements, hence the subtraction.
The bug can be triggered if a tuple contains a load of variable-length
elements, each of whose length is actually zero (i.e. empty arrays).
Includes a unit test.
oss-fuzz#9801
Signed-off-by: Philip Withnall <withnall@endlessm.com>
---
glib/gvariant-serialiser.c | 3 +++
glib/tests/gvariant.c | 28 ++++++++++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
index 69f183121..96df54e23 100644
--- a/glib/gvariant-serialiser.c
+++ b/glib/gvariant-serialiser.c
@@ -1065,6 +1065,9 @@ gvs_tuple_is_normal (GVariantSerialised value)
break;
case G_VARIANT_MEMBER_ENDING_OFFSET:
+ if (offset_ptr < offset_size)
+ return FALSE;
+
offset_ptr -= offset_size;
if (offset_ptr < offset)
diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
index de8e42d0b..a5095a380 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -4631,6 +4631,30 @@ test_stack_dict_init (void)
g_variant_unref (variant);
}
+/* Test checking arbitrary binary data for normal form. This time, its a tuple
+ * with invalid element ends. */
+static void
+test_normal_checking_tuples (void)
+{
+ const guint8 data[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 'a', '(', 'a', 'o', 'a', 'o', 'a', 'a', 'o', 'a', 'a', 'o', ')'
+ };
+ gsize size = sizeof (data);
+ GVariant *variant = NULL;
+ GVariant *normal_variant = NULL;
+
+ variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, data, size,
+ FALSE, NULL, NULL);
+ g_assert_nonnull (variant);
+
+ normal_variant = g_variant_get_normal_form (variant);
+ g_assert_nonnull (normal_variant);
+
+ g_variant_unref (normal_variant);
+ g_variant_unref (variant);
+}
+
int
main (int argc, char **argv)
{
@@ -4692,5 +4716,9 @@ main (int argc, char **argv)
g_test_add_func ("/gvariant/stack-builder-init", test_stack_builder_init);
g_test_add_func ("/gvariant/stack-dict-init", test_stack_dict_init);
+
+ g_test_add_func ("/gvariant/normal-checking/tuples",
+ test_normal_checking_tuples);
+
return g_test_run ();
}
--
2.19.1