File 0003-gvariant-Check-array-offsets-against-serialised-data.patch of Package glib2.11799
From 3691b749fffc1f97a9e3c974321da3be49b2f017 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Fri, 7 Sep 2018 22:26:05 +0100
Subject: [PATCH 03/15] gvariant: Check array offsets against serialised data
length
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When getting a child from a serialised variable array, check its offset
against the length of the serialised data of the array (excluding the
length of the offset table). The offset was already checked against the
length of the entire serialised array (including the offset table) — but a
child should not be able to start inside the offset table.
A test is included.
oss-fuzz#9803
Signed-off-by: Philip Withnall <withnall@endlessm.com>
---
glib/gvariant-serialiser.c | 2 +-
glib/tests/gvariant.c | 26 ++++++++++++++++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
index fe0bcf0aa..aa71d3c1c 100644
--- a/glib/gvariant-serialiser.c
+++ b/glib/gvariant-serialiser.c
@@ -694,7 +694,7 @@ gvs_variable_sized_array_get_child (GVariantSerialised value,
(offset_size * index_),
offset_size);
- if (start < end && end <= value.size)
+ if (start < end && end <= value.size && end <= last_end)
{
child.data = value.data + start;
child.size = end - start;
diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
index 51fa0f02b..671fdd94c 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -4715,6 +4715,30 @@ test_normal_checking_tuples (void)
g_variant_unref (variant);
}
+/* Test that an array with invalidly large values in its offset table is
+ * normalised successfully without looping infinitely. */
+static void
+test_normal_checking_array_offsets (void)
+{
+ const guint8 data[] = {
+ 0x07, 0xe5, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
+ 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'g',
+ };
+ 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)
{
@@ -4783,6 +4807,8 @@ main (int argc, char **argv)
g_test_add_func ("/gvariant/normal-checking/tuples",
test_normal_checking_tuples);
+ g_test_add_func ("/gvariant/normal-checking/array-offsets",
+ test_normal_checking_array_offsets);
g_test_add_func ("/gvariant/recursion-limits/variant-in-variant",
test_recursion_limits_variant_in_variant);
--
2.14.4