File 0005-gvariant-Limit-GVariant-strings-to-G_MAXSSIZE.patch of Package glib2.23781

From 6602176793abcaf954d0cb622a467fb8887820eb Mon Sep 17 00:00:00 2001
From: Philip Withnall <withnall@endlessm.com>
Date: Tue, 18 Sep 2018 13:29:18 +0100
Subject: [PATCH 05/15] gvariant: Limit GVariant strings to G_MAXSSIZE
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When validating a string to see if it’s valid UTF-8, we pass a gsize to
g_utf8_validate(), which only takes a gssize. For large gsize values,
this will result in the gssize actually being negative, which will
change g_utf8_validate()’s behaviour to stop at the first nul byte. That
would allow subsequent nul bytes through the string validator, against
its documented behaviour.

Add a test case.

oss-fuzz#10319

Signed-off-by: Philip Withnall <withnall@endlessm.com>
---
 glib/gvariant-serialiser.c |  3 ++-
 glib/tests/gvariant.c      | 26 ++++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
index 643894919..bbdcc7a0c 100644
--- a/glib/gvariant-serialiser.c
+++ b/glib/gvariant-serialiser.c
@@ -1643,6 +1643,7 @@ g_variant_serialiser_is_string (gconstpointer data,
   const gchar *expected_end;
   const gchar *end;
 
+  /* Strings must end with a nul terminator. */
   if (size == 0)
     return FALSE;
 
@@ -1651,7 +1652,7 @@ g_variant_serialiser_is_string (gconstpointer data,
   if (*expected_end != '\0')
     return FALSE;
 
-  g_utf8_validate (data, size, &end);
+  g_utf8_validate_len (data, size, &end);
 
   return end == expected_end;
 }
diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
index 48e4b15a8..e4c1390a9 100644
--- a/glib/tests/gvariant.c
+++ b/glib/tests/gvariant.c
@@ -4831,6 +4831,30 @@ test_normal_checking_tuple_offsets (void)
   g_variant_unref (variant);
 }
 
+/* Test that an empty object path is normalised successfully to the base object
+ * path, ‘/’. */
+static void
+test_normal_checking_empty_object_path (void)
+{
+  const guint8 data[] = {
+    0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
+    '(', 'h', '(', 'a', 'i', 'a', 'b', 'i', '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)
 {
@@ -4903,6 +4927,8 @@ main (int argc, char **argv)
                    test_normal_checking_array_offsets);
   g_test_add_func ("/gvariant/normal-checking/tuple-offsets",
                    test_normal_checking_tuple_offsets);
+  g_test_add_func ("/gvariant/normal-checking/empty-object-path",
+                   test_normal_checking_empty_object_path);
 
   g_test_add_func ("/gvariant/recursion-limits/variant-in-variant",
                    test_recursion_limits_variant_in_variant);
-- 
2.41.0

openSUSE Build Service is sponsored by