[glib: 3/16] gvariant: Check array offsets against serialised data length
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 3/16] gvariant: Check array offsets against serialised data length
- Date: Tue, 23 Oct 2018 04:30:51 +0000 (UTC)
commit 5e0b12df1a2e1d5669c0c7e493c45cb2a1f62748
Author: Philip Withnall <withnall endlessm com>
Date: Fri Sep 7 22:26:05 2018 +0100
gvariant: Check array offsets against serialised data length
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 8b1f7a6cb..1ab535534 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -4817,6 +4817,30 @@ test_recursion_limits_array_in_variant (void)
g_variant_unref (wrapper_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)
{
@@ -4885,6 +4909,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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]