glib2/0004-gvariant-Check-tuple-offsets-against-serialised-data.patch
Dominique Leuenberger 8eed20495d Accepting request 644162 from home:sreeves1:branches:GNOME:Factory
- 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
2018-10-24 12:56:55 +00:00

108 lines
3.8 KiB
Diff

From 183eed2b38b1d2fc3e6b149d7ac4cc062a619b48 Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Fri, 7 Sep 2018 22:28:37 +0100
Subject: [PATCH 04/15] gvariant: Check tuple offsets against serialised data
length
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
As with the previous commit, when getting a child from a serialised
tuple, check its offset against the length of the serialised data of the
tuple (excluding the length of the offset table). The offset was already
checked against the length of the entire serialised tuple (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 | 16 ++++++++++++++--
glib/tests/gvariant.c | 26 ++++++++++++++++++++++++++
2 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
index aa71d3c1c..643894919 100644
--- a/glib/gvariant-serialiser.c
+++ b/glib/gvariant-serialiser.c
@@ -870,7 +870,7 @@ gvs_tuple_get_child (GVariantSerialised value,
const GVariantMemberInfo *member_info;
GVariantSerialised child = { 0, };
gsize offset_size;
- gsize start, end;
+ gsize start, end, last_end;
member_info = g_variant_type_info_member_info (value.type_info, index_);
child.type_info = g_variant_type_info_ref (member_info->type_info);
@@ -940,7 +940,19 @@ gvs_tuple_get_child (GVariantSerialised value,
offset_size * (member_info->i + 2),
offset_size);
- if (start < end && end <= value.size)
+ /* The child should not extend into the offset table. */
+ if (index_ != g_variant_type_info_n_members (value.type_info) - 1)
+ {
+ GVariantSerialised last_child;
+ last_child = gvs_tuple_get_child (value,
+ g_variant_type_info_n_members (value.type_info) - 1);
+ last_end = last_child.data + last_child.size - value.data;
+ g_variant_type_info_unref (last_child.type_info);
+ }
+ else
+ last_end = end;
+
+ 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 671fdd94c..1af1466cc 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -4739,6 +4739,30 @@ test_normal_checking_array_offsets (void)
g_variant_unref (variant);
}
+/* Test that a tuple with invalidly large values in its offset table is
+ * normalised successfully without looping infinitely. */
+static void
+test_normal_checking_tuple_offsets (void)
+{
+ const guint8 data[] = {
+ 0x07, 0xe5, 0x00, 0x07, 0x00, 0x07,
+ '(', 'a', 's', 'a', 's', 'a', 's', 'a', 's', 'a', 's', 'a', 's', ')',
+ };
+ 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)
{
@@ -4809,6 +4833,8 @@ main (int argc, char **argv)
test_normal_checking_tuples);
g_test_add_func ("/gvariant/normal-checking/array-offsets",
test_normal_checking_array_offsets);
+ g_test_add_func ("/gvariant/normal-checking/tuple-offsets",
+ test_normal_checking_tuple_offsets);
g_test_add_func ("/gvariant/recursion-limits/variant-in-variant",
test_recursion_limits_variant_in_variant);
--
2.14.4