summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32643.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32643.patch')
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32643.patch154
1 files changed, 154 insertions, 0 deletions
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32643.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32643.patch
new file mode 100644
index 0000000000..9c0867bf5f
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32643.patch
@@ -0,0 +1,154 @@
1From 78da5faccb3e065116b75b3ff87ff55381da6c76 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Thu, 17 Aug 2023 11:24:43 +0000
4Subject: [PATCH] gvariant: Check offset table doesn't fall outside variant
5 bounds
6
7When dereferencing the first entry in the offset table for a tuple,
8check that it doesn’t fall outside the bounds of the variant first.
9
10This prevents an out-of-bounds read from some non-normal tuples.
11
12This bug was introduced in commit 73d0aa81c2575a5c9ae77d.
13
14Includes a unit test, although the test will likely only catch the
15original bug if run with asan enabled.
16
17Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
18
19Fixes: #2840
20oss-fuzz#54302
21
22CVE: CVE-2023-32643
23Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/78da5faccb3e065116b75b3ff87ff55381da6c76]
24Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
25---
26 glib/gvariant-serialiser.c | 12 ++++++--
27 glib/tests/gvariant.c | 63 ++++++++++++++++++++++++++++++++++++++
28 2 files changed, 72 insertions(+), 3 deletions(-)
29
30diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
31index 5aa2cbc..4e50ed7 100644
32--- a/glib/gvariant-serialiser.c
33+++ b/glib/gvariant-serialiser.c
34@@ -979,7 +979,8 @@ gvs_tuple_get_member_bounds (GVariantSerialised value,
35
36 member_info = g_variant_type_info_member_info (value.type_info, index_);
37
38- if (member_info->i + 1)
39+ if (member_info->i + 1 &&
40+ offset_size * (member_info->i + 1) <= value.size)
41 member_start = gvs_read_unaligned_le (value.data + value.size -
42 offset_size * (member_info->i + 1),
43 offset_size);
44@@ -990,7 +991,8 @@ gvs_tuple_get_member_bounds (GVariantSerialised value,
45 member_start &= member_info->b;
46 member_start |= member_info->c;
47
48- if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST)
49+ if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST &&
50+ offset_size * (member_info->i + 1) <= value.size)
51 member_end = value.size - offset_size * (member_info->i + 1);
52
53 else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED)
54@@ -1001,11 +1003,15 @@ gvs_tuple_get_member_bounds (GVariantSerialised value,
55 member_end = member_start + fixed_size;
56 }
57
58- else /* G_VARIANT_MEMBER_ENDING_OFFSET */
59+ else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_OFFSET &&
60+ offset_size * (member_info->i + 2) <= value.size)
61 member_end = gvs_read_unaligned_le (value.data + value.size -
62 offset_size * (member_info->i + 2),
63 offset_size);
64
65+ else /* invalid */
66+ member_end = G_MAXSIZE;
67+
68 if (out_member_start != NULL)
69 *out_member_start = member_start;
70 if (out_member_end != NULL)
71diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
72index 679dd40..2eca8be 100644
73--- a/glib/tests/gvariant.c
74+++ b/glib/tests/gvariant.c
75@@ -5432,6 +5432,67 @@ test_normal_checking_tuple_offsets4 (void)
76 g_variant_unref (variant);
77 }
78
79+/* This is a regression test that dereferencing the first element in the offset
80+ * table doesn’t dereference memory before the start of the GVariant. The first
81+ * element in the offset table gives the offset of the final member in the
82+ * tuple (the offset table is stored in reverse), and the position of this final
83+ * member is needed to check that none of the tuple members overlap with the
84+ * offset table
85+ *
86+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2840 */
87+static void
88+test_normal_checking_tuple_offsets5 (void)
89+{
90+ /* A tuple of type (sss) in normal form would have an offset table with two
91+ * entries:
92+ * - The first entry (lowest index in the table) gives the offset of the
93+ * third `s` in the tuple, as the offset table is reversed compared to the
94+ * tuple members.
95+ * - The second entry (highest index in the table) gives the offset of the
96+ * second `s` in the tuple.
97+ * - The offset of the first `s` in the tuple is always 0.
98+ *
99+ * See §2.5.4 (Structures) of the GVariant specification for details, noting
100+ * that the table is only layed out this way because all three members of the
101+ * tuple have non-fixed sizes.
102+ *
103+ * It’s not clear whether the 0xaa data of this variant is part of the strings
104+ * in the tuple, or part of the offset table. It doesn’t really matter. This
105+ * is a regression test to check that the code to validate the offset table
106+ * doesn’t unconditionally try to access the first entry in the offset table
107+ * by subtracting the table size from the end of the GVariant data.
108+ *
109+ * In this non-normal case, that would result in an address off the start of
110+ * the GVariant data, and an out-of-bounds read, because the GVariant is one
111+ * byte long, but the offset table is calculated as two bytes long (with 1B
112+ * sized entries) from the tuple’s type.
113+ */
114+ const GVariantType *data_type = G_VARIANT_TYPE ("(sss)");
115+ const guint8 data[] = { 0xaa };
116+ gsize size = sizeof (data);
117+ GVariant *variant = NULL;
118+ GVariant *normal_variant = NULL;
119+ GVariant *expected = NULL;
120+
121+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2840");
122+
123+ variant = g_variant_new_from_data (data_type, data, size, FALSE, NULL, NULL);
124+ g_assert_nonnull (variant);
125+
126+ g_assert_false (g_variant_is_normal_form (variant));
127+
128+ normal_variant = g_variant_get_normal_form (variant);
129+ g_assert_nonnull (normal_variant);
130+
131+ expected = g_variant_new_parsed ("('', '', '')");
132+ g_assert_cmpvariant (expected, variant);
133+ g_assert_cmpvariant (expected, normal_variant);
134+
135+ g_variant_unref (expected);
136+ g_variant_unref (normal_variant);
137+ g_variant_unref (variant);
138+}
139+
140 /* Test that an otherwise-valid serialised GVariant is considered non-normal if
141 * its offset table entries are too wide.
142 *
143@@ -5680,6 +5741,8 @@ main (int argc, char **argv)
144 test_normal_checking_tuple_offsets3);
145 g_test_add_func ("/gvariant/normal-checking/tuple-offsets4",
146 test_normal_checking_tuple_offsets4);
147+ g_test_add_func ("/gvariant/normal-checking/tuple-offsets5",
148+ test_normal_checking_tuple_offsets5);
149 g_test_add_func ("/gvariant/normal-checking/tuple-offsets/minimal-sized",
150 test_normal_checking_tuple_offsets_minimal_sized);
151 g_test_add_func ("/gvariant/normal-checking/empty-object-path",
152--
1532.24.4
154