98 lines
3.2 KiB
Diff
98 lines
3.2 KiB
Diff
|
|
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,
|
|||
|
|
it’s 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, it’s 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
|
|||
|
|
|