summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core
diff options
context:
space:
mode:
authorSiddharth Doshi <sdoshi@mvista.com>2023-10-15 21:00:39 +0530
committerSteve Sakoman <steve@sakoman.com>2023-10-20 05:35:30 -1000
commitaa99487732ab1ae453becdda08a3e72de0b7b269 (patch)
tree4e116f258212e3f01bcc04c3f1882916252b4cdf /meta/recipes-core
parent8ae21cd487a6147c3a2c9c2c0f0b2d5d149b7caf (diff)
downloadpoky-aa99487732ab1ae453becdda08a3e72de0b7b269.tar.gz
glib-2.0: Fix multiple vulnerabilities
CVE's Fixed: CVE-2023-29499: glib: GVariant offset table entry size is not checked in is_normal() CVE-2023-32611: glib: g_variant_byteswap() can take a long time with some non-normal inputs CVE-2023-32636: glib: Timeout in fuzz_variant_text CVE-2023-32643: glib: Heap-buffer-overflow in g_variant_serialised_get_child CVE-2023-32665: glib: GVariant deserialisation does not match spec for non-normal data (From OE-Core rev: b576beba80d44e67762d46bf3bc2f14c05bc0f6b) Signed-off-by: Siddharth Doshi <sdoshi@mvista.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
Diffstat (limited to 'meta/recipes-core')
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-29499.patch290
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32611-0001.patch89
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32611-0002.patch255
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32636.patch49
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32643.patch154
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0001.patch103
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0002.patch210
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0003.patch417
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0004.patch113
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0005.patch80
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0006.patch396
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0007.patch49
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0008.patch394
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0009.patch97
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0_2.62.6.bb14
15 files changed, 2710 insertions, 0 deletions
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-29499.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-29499.patch
new file mode 100644
index 0000000000..ce90586290
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-29499.patch
@@ -0,0 +1,290 @@
1From 5f4485c4ff57fdefb1661531788def7ca5a47328 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Thu, 17 Aug 2023 04:19:44 +0000
4Subject: [PATCH] gvariant-serialiser: Check offset table entry size is minimal
5
6The entries in an offset table (which is used for variable sized arrays
7and tuples containing variable sized members) are sized so that they can
8address every byte in the overall variant.
9
10The specification requires that for a variant to be in normal form, its
11offset table entries must be the minimum width such that they can
12address every byte in the variant.
13
14That minimality requirement was not checked in
15`g_variant_is_normal_form()`, leading to two different byte arrays being
16interpreted as the normal form of a given variant tree. That kind of
17confusion could potentially be exploited, and is certainly a bug.
18
19Fix it by adding the necessary checks on offset table entry width, and
20unit tests.
21
22Spotted by William Manley.
23
24Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
25
26Fixes: #2794
27
28CVE: CVE-2023-29499
29Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/5f4485c4ff57fdefb1661531788def7ca5a47328]
30Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
31---
32 glib/gvariant-serialiser.c | 19 +++-
33 glib/tests/gvariant.c | 176 +++++++++++++++++++++++++++++++++++++
34 2 files changed, 194 insertions(+), 1 deletion(-)
35
36diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
37index 0bf7243..5aa2cbc 100644
38--- a/glib/gvariant-serialiser.c
39+++ b/glib/gvariant-serialiser.c
40@@ -694,6 +694,10 @@ gvs_variable_sized_array_get_frame_offsets (GVariantSerialised value)
41 out.data_size = last_end;
42 out.array = value.data + last_end;
43 out.length = offsets_array_size / out.offset_size;
44+
45+ if (out.length > 0 && gvs_calculate_total_size (last_end, out.length) != value.size)
46+ return out; /* offset size not minimal */
47+
48 out.is_normal = TRUE;
49
50 return out;
51@@ -1201,6 +1205,7 @@ gvs_tuple_is_normal (GVariantSerialised value)
52 gsize length;
53 gsize offset;
54 gsize i;
55+ gsize offset_table_size;
56
57 /* as per the comment in gvs_tuple_get_child() */
58 if G_UNLIKELY (value.data == NULL && value.size != 0)
59@@ -1305,7 +1310,19 @@ gvs_tuple_is_normal (GVariantSerialised value)
60 }
61 }
62
63- return offset_ptr == offset;
64+ /* @offset_ptr has been counting backwards from the end of the variant, to
65+ * find the beginning of the offset table. @offset has been counting forwards
66+ * from the beginning of the variant to find the end of the data. They should
67+ * have met in the middle. */
68+ if (offset_ptr != offset)
69+ return FALSE;
70+
71+ offset_table_size = value.size - offset_ptr;
72+ if (value.size > 0 &&
73+ gvs_calculate_total_size (offset, offset_table_size / offset_size) != value.size)
74+ return FALSE; /* offset size not minimal */
75+
76+ return TRUE;
77 }
78
79 /* Variants {{{2
80diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
81index d640c81..4ce0e4f 100644
82--- a/glib/tests/gvariant.c
83+++ b/glib/tests/gvariant.c
84@@ -5092,6 +5092,86 @@ test_normal_checking_array_offsets2 (void)
85 g_variant_unref (variant);
86 }
87
88+/* Test that an otherwise-valid serialised GVariant is considered non-normal if
89+ * its offset table entries are too wide.
90+ *
91+ * See §2.3.6 (Framing Offsets) of the GVariant specification. */
92+static void
93+test_normal_checking_array_offsets_minimal_sized (void)
94+{
95+ GVariantBuilder builder;
96+ gsize i;
97+ GVariant *aay_constructed = NULL;
98+ const guint8 *data = NULL;
99+ guint8 *data_owned = NULL;
100+ GVariant *aay_deserialised = NULL;
101+ GVariant *aay_normalised = NULL;
102+
103+ /* Construct an array of type aay, consisting of 128 elements which are each
104+ * an empty array, i.e. `[[] * 128]`. This is chosen because the inner
105+ * elements are variable sized (making the outer array variable sized, so it
106+ * must have an offset table), but they are also zero-sized when serialised.
107+ * So the serialised representation of @aay_constructed consists entirely of
108+ * its offset table, which is entirely zeroes.
109+ *
110+ * The array is chosen to be 128 elements long because that means offset
111+ * table entries which are 1 byte long. If the elements in the array were
112+ * non-zero-sized (to the extent that the overall array is ≥256 bytes long),
113+ * the offset table entries would end up being 2 bytes long. */
114+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("aay"));
115+
116+ for (i = 0; i < 128; i++)
117+ g_variant_builder_add_value (&builder, g_variant_new_array (G_VARIANT_TYPE_BYTE, NULL, 0));
118+
119+ aay_constructed = g_variant_builder_end (&builder);
120+
121+ /* Verify that the constructed array is in normal form, and its serialised
122+ * form is `b'\0' * 128`. */
123+ g_assert_true (g_variant_is_normal_form (aay_constructed));
124+ g_assert_cmpuint (g_variant_n_children (aay_constructed), ==, 128);
125+ g_assert_cmpuint (g_variant_get_size (aay_constructed), ==, 128);
126+
127+ data = g_variant_get_data (aay_constructed);
128+ for (i = 0; i < g_variant_get_size (aay_constructed); i++)
129+ g_assert_cmpuint (data[i], ==, 0);
130+
131+ /* Construct a serialised `aay` GVariant which is `b'\0' * 256`. This has to
132+ * be a non-normal form of `[[] * 128]`, with 2-byte-long offset table
133+ * entries, because each offset table entry has to be able to reference all of
134+ * the byte boundaries in the container. All the entries in the offset table
135+ * are zero, so all the elements of the array are zero-sized. */
136+ data = data_owned = g_malloc0 (256);
137+ aay_deserialised = g_variant_new_from_data (G_VARIANT_TYPE ("aay"),
138+ data,
139+ 256,
140+ FALSE,
141+ g_free,
142+ g_steal_pointer (&data_owned));
143+
144+ g_assert_false (g_variant_is_normal_form (aay_deserialised));
145+ g_assert_cmpuint (g_variant_n_children (aay_deserialised), ==, 128);
146+ g_assert_cmpuint (g_variant_get_size (aay_deserialised), ==, 256);
147+
148+ data = g_variant_get_data (aay_deserialised);
149+ for (i = 0; i < g_variant_get_size (aay_deserialised); i++)
150+ g_assert_cmpuint (data[i], ==, 0);
151+
152+ /* Get its normal form. That should change the serialised size. */
153+ aay_normalised = g_variant_get_normal_form (aay_deserialised);
154+
155+ g_assert_true (g_variant_is_normal_form (aay_normalised));
156+ g_assert_cmpuint (g_variant_n_children (aay_normalised), ==, 128);
157+ g_assert_cmpuint (g_variant_get_size (aay_normalised), ==, 128);
158+
159+ data = g_variant_get_data (aay_normalised);
160+ for (i = 0; i < g_variant_get_size (aay_normalised); i++)
161+ g_assert_cmpuint (data[i], ==, 0);
162+
163+ g_variant_unref (aay_normalised);
164+ g_variant_unref (aay_deserialised);
165+ g_variant_unref (aay_constructed);
166+}
167+
168 /* Test that a tuple with invalidly large values in its offset table is
169 * normalised successfully without looping infinitely. */
170 static void
171@@ -5286,6 +5366,98 @@ test_normal_checking_tuple_offsets4 (void)
172 g_variant_unref (variant);
173 }
174
175+/* Test that an otherwise-valid serialised GVariant is considered non-normal if
176+ * its offset table entries are too wide.
177+ *
178+ * See §2.3.6 (Framing Offsets) of the GVariant specification. */
179+static void
180+test_normal_checking_tuple_offsets_minimal_sized (void)
181+{
182+ GString *type_string = NULL;
183+ GVariantBuilder builder;
184+ gsize i;
185+ GVariant *ray_constructed = NULL;
186+ const guint8 *data = NULL;
187+ guint8 *data_owned = NULL;
188+ GVariant *ray_deserialised = NULL;
189+ GVariant *ray_normalised = NULL;
190+
191+ /* Construct a tuple of type (ay…ay), consisting of 129 members which are each
192+ * an empty array, i.e. `([] * 129)`. This is chosen because the inner
193+ * members are variable sized, so the outer tuple must have an offset table,
194+ * but they are also zero-sized when serialised. So the serialised
195+ * representation of @ray_constructed consists entirely of its offset table,
196+ * which is entirely zeroes.
197+ *
198+ * The tuple is chosen to be 129 members long because that means it has 128
199+ * offset table entries which are 1 byte long each. If the members in the
200+ * tuple were non-zero-sized (to the extent that the overall tuple is ≥256
201+ * bytes long), the offset table entries would end up being 2 bytes long.
202+ *
203+ * 129 members are used unlike 128 array elements in
204+ * test_normal_checking_array_offsets_minimal_sized(), because the last member
205+ * in a tuple never needs an offset table entry. */
206+ type_string = g_string_new ("");
207+ g_string_append_c (type_string, '(');
208+ for (i = 0; i < 129; i++)
209+ g_string_append (type_string, "ay");
210+ g_string_append_c (type_string, ')');
211+
212+ g_variant_builder_init (&builder, G_VARIANT_TYPE (type_string->str));
213+
214+ for (i = 0; i < 129; i++)
215+ g_variant_builder_add_value (&builder, g_variant_new_array (G_VARIANT_TYPE_BYTE, NULL, 0));
216+
217+ ray_constructed = g_variant_builder_end (&builder);
218+
219+ /* Verify that the constructed tuple is in normal form, and its serialised
220+ * form is `b'\0' * 128`. */
221+ g_assert_true (g_variant_is_normal_form (ray_constructed));
222+ g_assert_cmpuint (g_variant_n_children (ray_constructed), ==, 129);
223+ g_assert_cmpuint (g_variant_get_size (ray_constructed), ==, 128);
224+
225+ data = g_variant_get_data (ray_constructed);
226+ for (i = 0; i < g_variant_get_size (ray_constructed); i++)
227+ g_assert_cmpuint (data[i], ==, 0);
228+
229+ /* Construct a serialised `(ay…ay)` GVariant which is `b'\0' * 256`. This has
230+ * to be a non-normal form of `([] * 129)`, with 2-byte-long offset table
231+ * entries, because each offset table entry has to be able to reference all of
232+ * the byte boundaries in the container. All the entries in the offset table
233+ * are zero, so all the members of the tuple are zero-sized. */
234+ data = data_owned = g_malloc0 (256);
235+ ray_deserialised = g_variant_new_from_data (G_VARIANT_TYPE (type_string->str),
236+ data,
237+ 256,
238+ FALSE,
239+ g_free,
240+ g_steal_pointer (&data_owned));
241+
242+ g_assert_false (g_variant_is_normal_form (ray_deserialised));
243+ g_assert_cmpuint (g_variant_n_children (ray_deserialised), ==, 129);
244+ g_assert_cmpuint (g_variant_get_size (ray_deserialised), ==, 256);
245+
246+ data = g_variant_get_data (ray_deserialised);
247+ for (i = 0; i < g_variant_get_size (ray_deserialised); i++)
248+ g_assert_cmpuint (data[i], ==, 0);
249+
250+ /* Get its normal form. That should change the serialised size. */
251+ ray_normalised = g_variant_get_normal_form (ray_deserialised);
252+
253+ g_assert_true (g_variant_is_normal_form (ray_normalised));
254+ g_assert_cmpuint (g_variant_n_children (ray_normalised), ==, 129);
255+ g_assert_cmpuint (g_variant_get_size (ray_normalised), ==, 128);
256+
257+ data = g_variant_get_data (ray_normalised);
258+ for (i = 0; i < g_variant_get_size (ray_normalised); i++)
259+ g_assert_cmpuint (data[i], ==, 0);
260+
261+ g_variant_unref (ray_normalised);
262+ g_variant_unref (ray_deserialised);
263+ g_variant_unref (ray_constructed);
264+ g_string_free (type_string, TRUE);
265+}
266+
267 /* Test that an empty object path is normalised successfully to the base object
268 * path, ‘/’. */
269 static void
270@@ -5431,6 +5603,8 @@ main (int argc, char **argv)
271 test_normal_checking_array_offsets);
272 g_test_add_func ("/gvariant/normal-checking/array-offsets2",
273 test_normal_checking_array_offsets2);
274+ g_test_add_func ("/gvariant/normal-checking/array-offsets/minimal-sized",
275+ test_normal_checking_array_offsets_minimal_sized);
276 g_test_add_func ("/gvariant/normal-checking/tuple-offsets",
277 test_normal_checking_tuple_offsets);
278 g_test_add_func ("/gvariant/normal-checking/tuple-offsets2",
279@@ -5439,6 +5613,8 @@ main (int argc, char **argv)
280 test_normal_checking_tuple_offsets3);
281 g_test_add_func ("/gvariant/normal-checking/tuple-offsets4",
282 test_normal_checking_tuple_offsets4);
283+ g_test_add_func ("/gvariant/normal-checking/tuple-offsets/minimal-sized",
284+ test_normal_checking_tuple_offsets_minimal_sized);
285 g_test_add_func ("/gvariant/normal-checking/empty-object-path",
286 test_normal_checking_empty_object_path);
287
288--
2892.24.4
290
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32611-0001.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32611-0001.patch
new file mode 100644
index 0000000000..b2187f2af9
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32611-0001.patch
@@ -0,0 +1,89 @@
1From 1deacdd4e8e35a5cf1417918ca4f6b0afa6409b1 Mon Sep 17 00:00:00 2001
2From: William Manley <will@stb-tester.com>
3Date: Wed, 9 Aug 2023 10:04:49 +0000
4Subject: [PATCH] gvariant-core: Consolidate construction of
5 `GVariantSerialised`
6
7So I only need to change it in one place.
8
9This introduces no functional changes.
10
11Helps: #2121
12
13CVE: CVE-2023-32665
14Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/1deacdd4e8e35a5cf1417918ca4f6b0afa6409b1]
15Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
16---
17 glib/gvariant.c | 8 +++++---
18 glib/tests/gvariant.c | 24 ++++++++++++++++++++++++
19 2 files changed, 29 insertions(+), 3 deletions(-)
20
21diff --git a/glib/gvariant.c b/glib/gvariant.c
22index 8ba701e..4dbd9e8 100644
23--- a/glib/gvariant.c
24+++ b/glib/gvariant.c
25@@ -5952,14 +5952,16 @@ g_variant_byteswap (GVariant *value)
26 g_variant_serialised_byteswap (serialised);
27
28 bytes = g_bytes_new_take (serialised.data, serialised.size);
29- new = g_variant_new_from_bytes (g_variant_get_type (value), bytes, TRUE);
30+ new = g_variant_ref_sink (g_variant_new_from_bytes (g_variant_get_type (value), bytes, TRUE));
31 g_bytes_unref (bytes);
32 }
33 else
34 /* contains no multi-byte data */
35- new = value;
36+ new = g_variant_get_normal_form (value);
37
38- return g_variant_ref_sink (new);
39+ g_assert (g_variant_is_trusted (new));
40+
41+ return g_steal_pointer (&new);
42 }
43
44 /**
45diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
46index 4ce0e4f..3dda08e 100644
47--- a/glib/tests/gvariant.c
48+++ b/glib/tests/gvariant.c
49@@ -3834,6 +3834,29 @@ test_gv_byteswap (void)
50 g_free (string);
51 }
52
53+static void
54+test_gv_byteswap_non_normal_non_aligned (void)
55+{
56+ const guint8 data[] = { 0x02 };
57+ GVariant *v = NULL;
58+ GVariant *v_byteswapped = NULL;
59+
60+ g_test_summary ("Test that calling g_variant_byteswap() on a variant which "
61+ "is in non-normal form and doesn’t need byteswapping returns "
62+ "the same variant in normal form.");
63+
64+ v = g_variant_new_from_data (G_VARIANT_TYPE_BOOLEAN, data, sizeof (data), FALSE, NULL, NULL);
65+ g_assert_false (g_variant_is_normal_form (v));
66+
67+ v_byteswapped = g_variant_byteswap (v);
68+ g_assert_true (g_variant_is_normal_form (v_byteswapped));
69+
70+ g_assert_cmpvariant (v, v_byteswapped);
71+
72+ g_variant_unref (v);
73+ g_variant_unref (v_byteswapped);
74+}
75+
76 static void
77 test_parser (void)
78 {
79@@ -5570,6 +5593,7 @@ main (int argc, char **argv)
80 g_test_add_func ("/gvariant/builder-memory", test_builder_memory);
81 g_test_add_func ("/gvariant/hashing", test_hashing);
82 g_test_add_func ("/gvariant/byteswap", test_gv_byteswap);
83+ g_test_add_func ("/gvariant/byteswap/non-normal-non-aligned", test_gv_byteswap_non_normal_non_aligned);
84 g_test_add_func ("/gvariant/parser", test_parses);
85 g_test_add_func ("/gvariant/parser/integer-bounds", test_parser_integer_bounds);
86 g_test_add_func ("/gvariant/parser/recursion", test_parser_recursion);
87--
882.24.4
89
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32611-0002.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32611-0002.patch
new file mode 100644
index 0000000000..9167ea624f
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32611-0002.patch
@@ -0,0 +1,255 @@
1From 446e69f5edd72deb2196dee36bbaf8056caf6948 Mon Sep 17 00:00:00 2001
2From: William Manley <will@stb-tester.com>
3Date: Wed, 9 Aug 2023 10:39:34 +0000
4Subject: [PATCH] gvariant-serialiser: Factor out functions for dealing with
5 framing offsets
6
7This introduces no functional changes.
8
9Helps: #2121
10
11CVE: CVE-2023-32665
12Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/446e69f5edd72deb2196dee36bbaf8056caf6948]
13Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
14---
15 glib/gvariant.c | 81 +++++++++++++++++++++++++++++++++----------
16 glib/tests/gvariant.c | 57 ++++++++++++++++++++++++++----
17 2 files changed, 112 insertions(+), 26 deletions(-)
18
19diff --git a/glib/gvariant.c b/glib/gvariant.c
20index 4dbd9e8..a80c2c9 100644
21--- a/glib/gvariant.c
22+++ b/glib/gvariant.c
23@@ -5788,7 +5788,8 @@ g_variant_iter_loop (GVariantIter *iter,
24
25 /* Serialised data {{{1 */
26 static GVariant *
27-g_variant_deep_copy (GVariant *value)
28+g_variant_deep_copy (GVariant *value,
29+ gboolean byteswap)
30 {
31 switch (g_variant_classify (value))
32 {
33@@ -5806,7 +5807,7 @@ g_variant_deep_copy (GVariant *value)
34 for (i = 0, n_children = g_variant_n_children (value); i < n_children; i++)
35 {
36 GVariant *child = g_variant_get_child_value (value, i);
37- g_variant_builder_add_value (&builder, g_variant_deep_copy (child));
38+ g_variant_builder_add_value (&builder, g_variant_deep_copy (child, byteswap));
39 g_variant_unref (child);
40 }
41
42@@ -5820,28 +5821,63 @@ g_variant_deep_copy (GVariant *value)
43 return g_variant_new_byte (g_variant_get_byte (value));
44
45 case G_VARIANT_CLASS_INT16:
46- return g_variant_new_int16 (g_variant_get_int16 (value));
47+ if (byteswap)
48+ return g_variant_new_int16 (GUINT16_SWAP_LE_BE (g_variant_get_int16 (value)));
49+ else
50+ return g_variant_new_int16 (g_variant_get_int16 (value));
51
52 case G_VARIANT_CLASS_UINT16:
53- return g_variant_new_uint16 (g_variant_get_uint16 (value));
54+ if (byteswap)
55+ return g_variant_new_uint16 (GUINT16_SWAP_LE_BE (g_variant_get_uint16 (value)));
56+ else
57+ return g_variant_new_uint16 (g_variant_get_uint16 (value));
58
59 case G_VARIANT_CLASS_INT32:
60- return g_variant_new_int32 (g_variant_get_int32 (value));
61+ if (byteswap)
62+ return g_variant_new_int32 (GUINT32_SWAP_LE_BE (g_variant_get_int32 (value)));
63+ else
64+ return g_variant_new_int32 (g_variant_get_int32 (value));
65
66 case G_VARIANT_CLASS_UINT32:
67- return g_variant_new_uint32 (g_variant_get_uint32 (value));
68+ if (byteswap)
69+ return g_variant_new_uint32 (GUINT32_SWAP_LE_BE (g_variant_get_uint32 (value)));
70+ else
71+ return g_variant_new_uint32 (g_variant_get_uint32 (value));
72
73 case G_VARIANT_CLASS_INT64:
74- return g_variant_new_int64 (g_variant_get_int64 (value));
75+ if (byteswap)
76+ return g_variant_new_int64 (GUINT64_SWAP_LE_BE (g_variant_get_int64 (value)));
77+ else
78+ return g_variant_new_int64 (g_variant_get_int64 (value));
79
80 case G_VARIANT_CLASS_UINT64:
81- return g_variant_new_uint64 (g_variant_get_uint64 (value));
82+ if (byteswap)
83+ return g_variant_new_uint64 (GUINT64_SWAP_LE_BE (g_variant_get_uint64 (value)));
84+ else
85+ return g_variant_new_uint64 (g_variant_get_uint64 (value));
86
87 case G_VARIANT_CLASS_HANDLE:
88- return g_variant_new_handle (g_variant_get_handle (value));
89+ if (byteswap)
90+ return g_variant_new_handle (GUINT32_SWAP_LE_BE (g_variant_get_handle (value)));
91+ else
92+ return g_variant_new_handle (g_variant_get_handle (value));
93
94 case G_VARIANT_CLASS_DOUBLE:
95- return g_variant_new_double (g_variant_get_double (value));
96+ if (byteswap)
97+ {
98+ /* We have to convert the double to a uint64 here using a union,
99+ * because a cast will round it numerically. */
100+ union
101+ {
102+ guint64 u64;
103+ gdouble dbl;
104+ } u1, u2;
105+ u1.dbl = g_variant_get_double (value);
106+ u2.u64 = GUINT64_SWAP_LE_BE (u1.u64);
107+ return g_variant_new_double (u2.dbl);
108+ }
109+ else
110+ return g_variant_new_double (g_variant_get_double (value));
111
112 case G_VARIANT_CLASS_STRING:
113 return g_variant_new_string (g_variant_get_string (value, NULL));
114@@ -5896,7 +5932,7 @@ g_variant_get_normal_form (GVariant *value)
115 if (g_variant_is_normal_form (value))
116 return g_variant_ref (value);
117
118- trusted = g_variant_deep_copy (value);
119+ trusted = g_variant_deep_copy (value, FALSE);
120 g_assert (g_variant_is_trusted (trusted));
121
122 return g_variant_ref_sink (trusted);
123@@ -5916,6 +5952,11 @@ g_variant_get_normal_form (GVariant *value)
124 * contain multi-byte numeric data. That include strings, booleans,
125 * bytes and containers containing only these things (recursively).
126 *
127+ * While this function can safely handle untrusted, non-normal data, it is
128+ * recommended to check whether the input is in normal form beforehand, using
129+ * g_variant_is_normal_form(), and to reject non-normal inputs if your
130+ * application can be strict about what inputs it rejects.
131+ *
132 * The returned value is always in normal form and is marked as trusted.
133 *
134 * Returns: (transfer full): the byteswapped form of @value
135@@ -5933,21 +5974,20 @@ g_variant_byteswap (GVariant *value)
136
137 g_variant_type_info_query (type_info, &alignment, NULL);
138
139- if (alignment)
140- /* (potentially) contains multi-byte numeric data */
141+ if (alignment && g_variant_is_normal_form (value))
142 {
143+ /* (potentially) contains multi-byte numeric data, but is also already in
144+ * normal form so we can use a faster byteswapping codepath on the
145+ * serialised data */
146 GVariantSerialised serialised = { 0, };
147- GVariant *trusted;
148 GBytes *bytes;
149
150- trusted = g_variant_get_normal_form (value);
151- serialised.type_info = g_variant_get_type_info (trusted);
152- serialised.size = g_variant_get_size (trusted);
153+ serialised.type_info = g_variant_get_type_info (value);
154+ serialised.size = g_variant_get_size (value);
155 serialised.data = g_malloc (serialised.size);
156 serialised.ordered_offsets_up_to = G_MAXSIZE; /* operating on the normal form */
157 serialised.checked_offsets_up_to = G_MAXSIZE;
158- g_variant_store (trusted, serialised.data);
159- g_variant_unref (trusted);
160+ g_variant_store (value, serialised.data);
161
162 g_variant_serialised_byteswap (serialised);
163
164@@ -5955,6 +5995,9 @@ g_variant_byteswap (GVariant *value)
165 new = g_variant_ref_sink (g_variant_new_from_bytes (g_variant_get_type (value), bytes, TRUE));
166 g_bytes_unref (bytes);
167 }
168+ else if (alignment)
169+ /* (potentially) contains multi-byte numeric data */
170+ new = g_variant_ref_sink (g_variant_deep_copy (value, TRUE));
171 else
172 /* contains no multi-byte data */
173 new = g_variant_get_normal_form (value);
174diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
175index 3dda08e..679dd40 100644
176--- a/glib/tests/gvariant.c
177+++ b/glib/tests/gvariant.c
178@@ -2284,24 +2284,67 @@ serialise_tree (TreeInstance *tree,
179 static void
180 test_byteswap (void)
181 {
182- GVariantSerialised one = { 0, }, two = { 0, };
183+ GVariantSerialised one = { 0, }, two = { 0, }, three = { 0, };
184 TreeInstance *tree;
185-
186+ GVariant *one_variant = NULL;
187+ GVariant *two_variant = NULL;
188+ GVariant *two_byteswapped = NULL;
189+ GVariant *three_variant = NULL;
190+ GVariant *three_byteswapped = NULL;
191+ guint8 *three_data_copy = NULL;
192+ gsize three_size_copy = 0;
193+
194+ /* Write a tree out twice, once normally and once byteswapped. */
195 tree = tree_instance_new (NULL, 3);
196 serialise_tree (tree, &one);
197
198+ one_variant = g_variant_new_from_data (G_VARIANT_TYPE (g_variant_type_info_get_type_string (one.type_info)),
199+ one.data, one.size, FALSE, NULL, NULL);
200+
201 i_am_writing_byteswapped = TRUE;
202 serialise_tree (tree, &two);
203+ serialise_tree (tree, &three);
204 i_am_writing_byteswapped = FALSE;
205
206- g_variant_serialised_byteswap (two);
207-
208- g_assert_cmpmem (one.data, one.size, two.data, two.size);
209- g_assert_cmpuint (one.depth, ==, two.depth);
210-
211+ /* Swap the first byteswapped one back using the function we want to test. */
212+ two_variant = g_variant_new_from_data (G_VARIANT_TYPE (g_variant_type_info_get_type_string (two.type_info)),
213+ two.data, two.size, FALSE, NULL, NULL);
214+ two_byteswapped = g_variant_byteswap (two_variant);
215+
216+ /* Make the second byteswapped one non-normal (hopefully), and then byteswap
217+ * it back using the function we want to test in its non-normal mode.
218+ * This might not work because it’s not necessarily possible to make an
219+ * arbitrary random variant non-normal. Adding a single zero byte to the end
220+ * often makes something non-normal but still readable. */
221+ three_size_copy = three.size + 1;
222+ three_data_copy = g_malloc (three_size_copy);
223+ memcpy (three_data_copy, three.data, three.size);
224+ three_data_copy[three.size] = '\0';
225+
226+ three_variant = g_variant_new_from_data (G_VARIANT_TYPE (g_variant_type_info_get_type_string (three.type_info)),
227+ three_data_copy, three_size_copy, FALSE, NULL, NULL);
228+ three_byteswapped = g_variant_byteswap (three_variant);
229+
230+ /* Check they’re the same. We can always compare @one_variant and
231+ * @two_byteswapped. We can only compare @two_byteswapped and
232+ * @three_byteswapped if @two_variant and @three_variant are equal: in that
233+ * case, the corruption to @three_variant was enough to make it non-normal but
234+ * not enough to change its value. */
235+ g_assert_cmpvariant (one_variant, two_byteswapped);
236+
237+ if (g_variant_equal (two_variant, three_variant))
238+ g_assert_cmpvariant (two_byteswapped, three_byteswapped);
239+
240+ g_variant_unref (three_byteswapped);
241+ g_variant_unref (three_variant);
242+ g_variant_unref (two_byteswapped);
243+ g_variant_unref (two_variant);
244+ g_variant_unref (one_variant);
245 tree_instance_free (tree);
246 g_free (one.data);
247 g_free (two.data);
248+ g_free (three.data);
249+ g_free (three_data_copy);
250 }
251
252 static void
253--
2542.24.4
255
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32636.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32636.patch
new file mode 100644
index 0000000000..533142b22a
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32636.patch
@@ -0,0 +1,49 @@
1From 21a204147b16539b3eda3143b32844c49e29f4d4 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Thu, 17 Aug 2023 11:33:49 +0000
4Subject: [PATCH] gvariant: Propagate trust when getting a child of a
5 serialised variant
6
7If a variant is trusted, that means all its children are trusted, so
8ensure that their checked offsets are set as such.
9
10This allows a lot of the offset table checks to be avoided when getting
11children from trusted serialised tuples, which speeds things up.
12
13No unit test is included because this is just a performance fix. If
14there are other slownesses, or regressions, in serialised `GVariant`
15performance, the fuzzing setup will catch them like it did this one.
16
17This change does reduce the time to run the oss-fuzz reproducer from 80s
18to about 0.7s on my machine.
19
20Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
21
22Fixes: #2841
23oss-fuzz#54314
24
25CVE: CVE-2023-32636
26Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/21a204147b16539b3eda3143b32844c49e29f4d4]
27Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
28---
29 glib/gvariant-core.c | 4 ++--
30 1 file changed, 2 insertions(+), 2 deletions(-)
31
32diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c
33index 1b9d5cc..ed57c70 100644
34--- a/glib/gvariant-core.c
35+++ b/glib/gvariant-core.c
36@@ -1173,8 +1173,8 @@ g_variant_get_child_value (GVariant *value,
37 child->contents.serialised.bytes =
38 g_bytes_ref (value->contents.serialised.bytes);
39 child->contents.serialised.data = s_child.data;
40- child->contents.serialised.ordered_offsets_up_to = s_child.ordered_offsets_up_to;
41- child->contents.serialised.checked_offsets_up_to = s_child.checked_offsets_up_to;
42+ child->contents.serialised.ordered_offsets_up_to = (value->state & STATE_TRUSTED) ? G_MAXSIZE : s_child.ordered_offsets_up_to;
43+ child->contents.serialised.checked_offsets_up_to = (value->state & STATE_TRUSTED) ? G_MAXSIZE : s_child.checked_offsets_up_to;
44
45 return child;
46 }
47--
482.24.4
49
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
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0001.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0001.patch
new file mode 100644
index 0000000000..9fc58341cb
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0001.patch
@@ -0,0 +1,103 @@
1From 1deacdd4e8e35a5cf1417918ca4f6b0afa6409b1 Mon Sep 17 00:00:00 2001
2From: William Manley <will@stb-tester.com>
3Date: Wed, 9 Aug 2023 10:04:49 +0000
4Subject: [PATCH] gvariant-core: Consolidate construction of
5 `GVariantSerialised`
6
7So I only need to change it in one place.
8
9This introduces no functional changes.
10
11Helps: #2121
12
13CVE: CVE-2023-32665
14Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/1deacdd4e8e35a5cf1417918ca4f6b0afa6409b1]
15Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
16---
17 glib/gvariant-core.c | 49 ++++++++++++++++++++++----------------------
18 1 file changed, 25 insertions(+), 24 deletions(-)
19
20diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c
21index 9397573..aa0e0a0 100644
22--- a/glib/gvariant-core.c
23+++ b/glib/gvariant-core.c
24@@ -349,6 +349,27 @@ g_variant_ensure_size (GVariant *value)
25 }
26 }
27
28+/* < private >
29+ * g_variant_to_serialised:
30+ * @value: a #GVariant
31+ *
32+ * Gets a GVariantSerialised for a GVariant in state STATE_SERIALISED.
33+ */
34+inline static GVariantSerialised
35+g_variant_to_serialised (GVariant *value)
36+{
37+ g_assert (value->state & STATE_SERIALISED);
38+ {
39+ GVariantSerialised serialised = {
40+ value->type_info,
41+ (gpointer) value->contents.serialised.data,
42+ value->size,
43+ value->depth,
44+ };
45+ return serialised;
46+ }
47+}
48+
49 /* < private >
50 * g_variant_serialise:
51 * @value: a #GVariant
52@@ -991,16 +1012,8 @@ g_variant_n_children (GVariant *value)
53 g_variant_lock (value);
54
55 if (value->state & STATE_SERIALISED)
56- {
57- GVariantSerialised serialised = {
58- value->type_info,
59- (gpointer) value->contents.serialised.data,
60- value->size,
61- value->depth,
62- };
63-
64- n_children = g_variant_serialised_n_children (serialised);
65- }
66+ n_children = g_variant_serialised_n_children (
67+ g_variant_to_serialised (value));
68 else
69 n_children = value->contents.tree.n_children;
70
71@@ -1061,12 +1074,7 @@ g_variant_get_child_value (GVariant *value,
72 }
73
74 {
75- GVariantSerialised serialised = {
76- value->type_info,
77- (gpointer) value->contents.serialised.data,
78- value->size,
79- value->depth,
80- };
81+ GVariantSerialised serialised = g_variant_to_serialised (value);
82 GVariantSerialised s_child;
83 GVariant *child;
84
85@@ -1179,14 +1187,7 @@ g_variant_is_normal_form (GVariant *value)
86
87 if (value->state & STATE_SERIALISED)
88 {
89- GVariantSerialised serialised = {
90- value->type_info,
91- (gpointer) value->contents.serialised.data,
92- value->size,
93- value->depth
94- };
95-
96- if (g_variant_serialised_is_normal (serialised))
97+ if (g_variant_serialised_is_normal (g_variant_to_serialised (value)))
98 value->state |= STATE_TRUSTED;
99 }
100 else
101--
1022.24.4
103
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0002.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0002.patch
new file mode 100644
index 0000000000..0e96b8d457
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0002.patch
@@ -0,0 +1,210 @@
1From 446e69f5edd72deb2196dee36bbaf8056caf6948 Mon Sep 17 00:00:00 2001
2From: William Manley <will@stb-tester.com>
3Date: Wed, 9 Aug 2023 10:39:34 +0000
4Subject: [PATCH] gvariant-serialiser: Factor out functions for dealing with
5 framing offsets
6
7This introduces no functional changes.
8
9Helps: #2121
10
11CVE: CVE-2023-32665
12Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/446e69f5edd72deb2196dee36bbaf8056caf6948]
13Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
14---
15 glib/gvariant-serialiser.c | 108 +++++++++++++++++++------------------
16 1 file changed, 57 insertions(+), 51 deletions(-)
17
18diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
19index 83e9d85..c7c2114 100644
20--- a/glib/gvariant-serialiser.c
21+++ b/glib/gvariant-serialiser.c
22@@ -633,30 +633,62 @@ gvs_calculate_total_size (gsize body_size,
23 return body_size + 8 * offsets;
24 }
25
26+struct Offsets
27+{
28+ gsize data_size;
29+
30+ guchar *array;
31+ gsize length;
32+ guint offset_size;
33+
34+ gboolean is_normal;
35+};
36+
37 static gsize
38-gvs_variable_sized_array_n_children (GVariantSerialised value)
39+gvs_offsets_get_offset_n (struct Offsets *offsets,
40+ gsize n)
41+{
42+ return gvs_read_unaligned_le (
43+ offsets->array + (offsets->offset_size * n), offsets->offset_size);
44+}
45+
46+static struct Offsets
47+gvs_variable_sized_array_get_frame_offsets (GVariantSerialised value)
48 {
49+ struct Offsets out = { 0, };
50 gsize offsets_array_size;
51- gsize offset_size;
52 gsize last_end;
53
54 if (value.size == 0)
55- return 0;
56-
57- offset_size = gvs_get_offset_size (value.size);
58+ {
59+ out.is_normal = TRUE;
60+ return out;
61+ }
62
63- last_end = gvs_read_unaligned_le (value.data + value.size -
64- offset_size, offset_size);
65+ out.offset_size = gvs_get_offset_size (value.size);
66+ last_end = gvs_read_unaligned_le (value.data + value.size - out.offset_size,
67+ out.offset_size);
68
69 if (last_end > value.size)
70- return 0;
71+ return out; /* offsets not normal */
72
73 offsets_array_size = value.size - last_end;
74
75- if (offsets_array_size % offset_size)
76- return 0;
77+ if (offsets_array_size % out.offset_size)
78+ return out; /* offsets not normal */
79+
80+ out.data_size = last_end;
81+ out.array = value.data + last_end;
82+ out.length = offsets_array_size / out.offset_size;
83+ out.is_normal = TRUE;
84
85- return offsets_array_size / offset_size;
86+ return out;
87+}
88+
89+static gsize
90+gvs_variable_sized_array_n_children (GVariantSerialised value)
91+{
92+ return gvs_variable_sized_array_get_frame_offsets (value).length;
93 }
94
95 static GVariantSerialised
96@@ -664,8 +696,9 @@ gvs_variable_sized_array_get_child (GVariantSerialised value,
97 gsize index_)
98 {
99 GVariantSerialised child = { 0, };
100- gsize offset_size;
101- gsize last_end;
102+
103+ struct Offsets offsets = gvs_variable_sized_array_get_frame_offsets (value);
104+
105 gsize start;
106 gsize end;
107
108@@ -673,18 +706,11 @@ gvs_variable_sized_array_get_child (GVariantSerialised value,
109 g_variant_type_info_ref (child.type_info);
110 child.depth = value.depth + 1;
111
112- offset_size = gvs_get_offset_size (value.size);
113-
114- last_end = gvs_read_unaligned_le (value.data + value.size -
115- offset_size, offset_size);
116-
117 if (index_ > 0)
118 {
119 guint alignment;
120
121- start = gvs_read_unaligned_le (value.data + last_end +
122- (offset_size * (index_ - 1)),
123- offset_size);
124+ start = gvs_offsets_get_offset_n (&offsets, index_ - 1);
125
126 g_variant_type_info_query (child.type_info, &alignment, NULL);
127 start += (-start) & alignment;
128@@ -692,11 +718,9 @@ gvs_variable_sized_array_get_child (GVariantSerialised value,
129 else
130 start = 0;
131
132- end = gvs_read_unaligned_le (value.data + last_end +
133- (offset_size * index_),
134- offset_size);
135+ end = gvs_offsets_get_offset_n (&offsets, index_);
136
137- if (start < end && end <= value.size && end <= last_end)
138+ if (start < end && end <= value.size && end <= offsets.data_size)
139 {
140 child.data = value.data + start;
141 child.size = end - start;
142@@ -768,34 +792,16 @@ static gboolean
143 gvs_variable_sized_array_is_normal (GVariantSerialised value)
144 {
145 GVariantSerialised child = { 0, };
146- gsize offsets_array_size;
147- guchar *offsets_array;
148- guint offset_size;
149 guint alignment;
150- gsize last_end;
151- gsize length;
152 gsize offset;
153 gsize i;
154
155- if (value.size == 0)
156- return TRUE;
157-
158- offset_size = gvs_get_offset_size (value.size);
159- last_end = gvs_read_unaligned_le (value.data + value.size -
160- offset_size, offset_size);
161+ struct Offsets offsets = gvs_variable_sized_array_get_frame_offsets (value);
162
163- if (last_end > value.size)
164+ if (!offsets.is_normal)
165 return FALSE;
166
167- offsets_array_size = value.size - last_end;
168-
169- if (offsets_array_size % offset_size)
170- return FALSE;
171-
172- offsets_array = value.data + value.size - offsets_array_size;
173- length = offsets_array_size / offset_size;
174-
175- if (length == 0)
176+ if (value.size != 0 && offsets.length == 0)
177 return FALSE;
178
179 child.type_info = g_variant_type_info_element (value.type_info);
180@@ -803,14 +809,14 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value)
181 child.depth = value.depth + 1;
182 offset = 0;
183
184- for (i = 0; i < length; i++)
185+ for (i = 0; i < offsets.length; i++)
186 {
187 gsize this_end;
188
189- this_end = gvs_read_unaligned_le (offsets_array + offset_size * i,
190- offset_size);
191+ this_end = gvs_read_unaligned_le (offsets.array + offsets.offset_size * i,
192+ offsets.offset_size);
193
194- if (this_end < offset || this_end > last_end)
195+ if (this_end < offset || this_end > offsets.data_size)
196 return FALSE;
197
198 while (offset & alignment)
199@@ -832,7 +838,7 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value)
200 offset = this_end;
201 }
202
203- g_assert (offset == last_end);
204+ g_assert (offset == offsets.data_size);
205
206 return TRUE;
207 }
208--
2092.24.4
210
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0003.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0003.patch
new file mode 100644
index 0000000000..e361cc7aad
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0003.patch
@@ -0,0 +1,417 @@
1From ade71fb544391b2e33e1859645726bfee0d5eaaf Mon Sep 17 00:00:00 2001
2From: William Manley <will@stb-tester.com>
3Date: Wed, 16 Aug 2023 03:12:21 +0000
4Subject: [PATCH] gvariant: Don't allow child elements to overlap with each
5 other
6
7If different elements of a variable sized array can overlap with each
8other then we can cause a `GVariant` to normalise to a much larger type.
9
10This commit changes the behaviour of `GVariant` with non-normal form data. If
11an invalid frame offset is found all subsequent elements are given their
12default value.
13
14When retrieving an element at index `n` we scan the frame offsets up to index
15`n` and if they are not in order we return an element with the default value
16for that type. This guarantees that elements don't overlap with each
17other. We remember the offset we've scanned up to so we don't need to
18repeat this work on subsequent accesses. We skip these checks for trusted
19data.
20
21Unfortunately this makes random access of untrusted data O(n) — at least
22on first access. It doesn't affect the algorithmic complexity of accessing
23elements in order, such as when using the `GVariantIter` interface. Also:
24the cost of validation will be amortised as the `GVariant` instance is
25continued to be used.
26
27I've implemented this with 4 different functions, 1 for each element size,
28rather than looping calling `gvs_read_unaligned_le` in the hope that the
29compiler will find it easy to optimise and should produce fairly tight
30code.
31
32Fixes: #2121
33
34CVE: CVE-2023-32665
35Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/ade71fb544391b2e33e1859645726bfee0d5eaaf]
36Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
37---
38 glib/gvariant-core.c | 35 ++++++++++++++++
39 glib/gvariant-serialiser.c | 86 ++++++++++++++++++++++++++++++++++++--
40 glib/gvariant-serialiser.h | 8 ++++
41 glib/tests/gvariant.c | 45 ++++++++++++++++++++
42 4 files changed, 171 insertions(+), 3 deletions(-)
43
44diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c
45index aa0e0a0..9b51e15 100644
46--- a/glib/gvariant-core.c
47+++ b/glib/gvariant-core.c
48@@ -65,6 +65,7 @@ struct _GVariant
49 {
50 GBytes *bytes;
51 gconstpointer data;
52+ gsize ordered_offsets_up_to;
53 } serialised;
54
55 struct
56@@ -162,6 +163,24 @@ struct _GVariant
57 * if .data pointed to the appropriate number of nul
58 * bytes.
59 *
60+ * .ordered_offsets_up_to: If ordered_offsets_up_to == n this means that all
61+ * the frame offsets up to and including the frame
62+ * offset determining the end of element n are in
63+ * order. This guarantees that the bytes of element
64+ * n don't overlap with any previous element.
65+ *
66+ * For trusted data this is set to G_MAXSIZE and we
67+ * don't check that the frame offsets are in order.
68+ *
69+ * Note: This doesn't imply the offsets are good in
70+ * any way apart from their ordering. In particular
71+ * offsets may be out of bounds for this value or
72+ * may imply that the data overlaps the frame
73+ * offsets themselves.
74+ *
75+ * This field is only relevant for arrays of non
76+ * fixed width types.
77+ *
78 * .tree: Only valid when the instance is in tree form.
79 *
80 * Note that accesses from other threads could result in
81@@ -365,6 +384,7 @@ g_variant_to_serialised (GVariant *value)
82 (gpointer) value->contents.serialised.data,
83 value->size,
84 value->depth,
85+ value->contents.serialised.ordered_offsets_up_to,
86 };
87 return serialised;
88 }
89@@ -396,6 +416,7 @@ g_variant_serialise (GVariant *value,
90 serialised.size = value->size;
91 serialised.data = data;
92 serialised.depth = value->depth;
93+ serialised.ordered_offsets_up_to = 0;
94
95 children = (gpointer *) value->contents.tree.children;
96 n_children = value->contents.tree.n_children;
97@@ -439,6 +460,15 @@ g_variant_fill_gvs (GVariantSerialised *serialised,
98 g_assert (serialised->size == value->size);
99 serialised->depth = value->depth;
100
101+ if (value->state & STATE_SERIALISED)
102+ {
103+ serialised->ordered_offsets_up_to = value->contents.serialised.ordered_offsets_up_to;
104+ }
105+ else
106+ {
107+ serialised->ordered_offsets_up_to = 0;
108+ }
109+
110 if (serialised->data)
111 /* g_variant_store() is a public API, so it
112 * it will reacquire the lock if it needs to.
113@@ -481,6 +511,7 @@ g_variant_ensure_serialised (GVariant *value)
114 bytes = g_bytes_new_take (data, value->size);
115 value->contents.serialised.data = g_bytes_get_data (bytes, NULL);
116 value->contents.serialised.bytes = bytes;
117+ value->contents.serialised.ordered_offsets_up_to = G_MAXSIZE;
118 value->state |= STATE_SERIALISED;
119 }
120 }
121@@ -561,6 +592,7 @@ g_variant_new_from_bytes (const GVariantType *type,
122 serialised.type_info = value->type_info;
123 serialised.data = (guchar *) g_bytes_get_data (bytes, &serialised.size);
124 serialised.depth = 0;
125+ serialised.ordered_offsets_up_to = trusted ? G_MAXSIZE : 0;
126
127 if (!g_variant_serialised_check (serialised))
128 {
129@@ -610,6 +642,8 @@ g_variant_new_from_bytes (const GVariantType *type,
130 value->contents.serialised.data = g_bytes_get_data (bytes, &value->size);
131 }
132
133+ value->contents.serialised.ordered_offsets_up_to = trusted ? G_MAXSIZE : 0;
134+
135 g_clear_pointer (&owned_bytes, g_bytes_unref);
136
137 return value;
138@@ -1108,6 +1142,7 @@ g_variant_get_child_value (GVariant *value,
139 child->contents.serialised.bytes =
140 g_bytes_ref (value->contents.serialised.bytes);
141 child->contents.serialised.data = s_child.data;
142+ child->contents.serialised.ordered_offsets_up_to = s_child.ordered_offsets_up_to;
143
144 return child;
145 }
146diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
147index c7c2114..fe0b1a4 100644
148--- a/glib/gvariant-serialiser.c
149+++ b/glib/gvariant-serialiser.c
150@@ -1,6 +1,7 @@
151 /*
152 * Copyright © 2007, 2008 Ryan Lortie
153 * Copyright © 2010 Codethink Limited
154+ * Copyright © 2020 William Manley
155 *
156 * This library is free software; you can redistribute it and/or
157 * modify it under the terms of the GNU Lesser General Public
158@@ -264,6 +265,7 @@ gvs_fixed_sized_maybe_get_child (GVariantSerialised value,
159 value.type_info = g_variant_type_info_element (value.type_info);
160 g_variant_type_info_ref (value.type_info);
161 value.depth++;
162+ value.ordered_offsets_up_to = 0;
163
164 return value;
165 }
166@@ -295,7 +297,7 @@ gvs_fixed_sized_maybe_serialise (GVariantSerialised value,
167 {
168 if (n_children)
169 {
170- GVariantSerialised child = { NULL, value.data, value.size, value.depth + 1 };
171+ GVariantSerialised child = { NULL, value.data, value.size, value.depth + 1, 0 };
172
173 gvs_filler (&child, children[0]);
174 }
175@@ -317,6 +319,7 @@ gvs_fixed_sized_maybe_is_normal (GVariantSerialised value)
176 /* proper element size: "Just". recurse to the child. */
177 value.type_info = g_variant_type_info_element (value.type_info);
178 value.depth++;
179+ value.ordered_offsets_up_to = 0;
180
181 return g_variant_serialised_is_normal (value);
182 }
183@@ -358,6 +361,7 @@ gvs_variable_sized_maybe_get_child (GVariantSerialised value,
184 value.data = NULL;
185
186 value.depth++;
187+ value.ordered_offsets_up_to = 0;
188
189 return value;
190 }
191@@ -388,7 +392,7 @@ gvs_variable_sized_maybe_serialise (GVariantSerialised value,
192 {
193 if (n_children)
194 {
195- GVariantSerialised child = { NULL, value.data, value.size - 1, value.depth + 1 };
196+ GVariantSerialised child = { NULL, value.data, value.size - 1, value.depth + 1, 0 };
197
198 /* write the data for the child. */
199 gvs_filler (&child, children[0]);
200@@ -408,6 +412,7 @@ gvs_variable_sized_maybe_is_normal (GVariantSerialised value)
201 value.type_info = g_variant_type_info_element (value.type_info);
202 value.size--;
203 value.depth++;
204+ value.ordered_offsets_up_to = 0;
205
206 return g_variant_serialised_is_normal (value);
207 }
208@@ -691,6 +696,32 @@ gvs_variable_sized_array_n_children (GVariantSerialised value)
209 return gvs_variable_sized_array_get_frame_offsets (value).length;
210 }
211
212+/* Find the index of the first out-of-order element in @data, assuming that
213+ * @data is an array of elements of given @type, starting at index @start and
214+ * containing a further @len-@start elements. */
215+#define DEFINE_FIND_UNORDERED(type) \
216+ static gsize \
217+ find_unordered_##type (const guint8 *data, gsize start, gsize len) \
218+ { \
219+ gsize off; \
220+ type current, previous; \
221+ \
222+ memcpy (&previous, data + start * sizeof (current), sizeof (current)); \
223+ for (off = (start + 1) * sizeof (current); off < len * sizeof (current); off += sizeof (current)) \
224+ { \
225+ memcpy (&current, data + off, sizeof (current)); \
226+ if (current < previous) \
227+ break; \
228+ previous = current; \
229+ } \
230+ return off / sizeof (current) - 1; \
231+ }
232+
233+DEFINE_FIND_UNORDERED (guint8);
234+DEFINE_FIND_UNORDERED (guint16);
235+DEFINE_FIND_UNORDERED (guint32);
236+DEFINE_FIND_UNORDERED (guint64);
237+
238 static GVariantSerialised
239 gvs_variable_sized_array_get_child (GVariantSerialised value,
240 gsize index_)
241@@ -706,6 +737,49 @@ gvs_variable_sized_array_get_child (GVariantSerialised value,
242 g_variant_type_info_ref (child.type_info);
243 child.depth = value.depth + 1;
244
245+ /* If the requested @index_ is beyond the set of indices whose framing offsets
246+ * have been checked, check the remaining offsets to see whether they’re
247+ * normal (in order, no overlapping array elements). */
248+ if (index_ > value.ordered_offsets_up_to)
249+ {
250+ switch (offsets.offset_size)
251+ {
252+ case 1:
253+ {
254+ value.ordered_offsets_up_to = find_unordered_guint8 (
255+ offsets.array, value.ordered_offsets_up_to, index_ + 1);
256+ break;
257+ }
258+ case 2:
259+ {
260+ value.ordered_offsets_up_to = find_unordered_guint16 (
261+ offsets.array, value.ordered_offsets_up_to, index_ + 1);
262+ break;
263+ }
264+ case 4:
265+ {
266+ value.ordered_offsets_up_to = find_unordered_guint32 (
267+ offsets.array, value.ordered_offsets_up_to, index_ + 1);
268+ break;
269+ }
270+ case 8:
271+ {
272+ value.ordered_offsets_up_to = find_unordered_guint64 (
273+ offsets.array, value.ordered_offsets_up_to, index_ + 1);
274+ break;
275+ }
276+ default:
277+ /* gvs_get_offset_size() only returns maximum 8 */
278+ g_assert_not_reached ();
279+ }
280+ }
281+
282+ if (index_ > value.ordered_offsets_up_to)
283+ {
284+ /* Offsets are invalid somewhere, so return an empty child. */
285+ return child;
286+ }
287+
288 if (index_ > 0)
289 {
290 guint alignment;
291@@ -840,6 +914,9 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value)
292
293 g_assert (offset == offsets.data_size);
294
295+ /* All offsets have now been checked. */
296+ value.ordered_offsets_up_to = G_MAXSIZE;
297+
298 return TRUE;
299 }
300
301@@ -1072,7 +1149,7 @@ gvs_tuple_is_normal (GVariantSerialised value)
302 for (i = 0; i < length; i++)
303 {
304 const GVariantMemberInfo *member_info;
305- GVariantSerialised child;
306+ GVariantSerialised child = { 0, };
307 gsize fixed_size;
308 guint alignment;
309 gsize end;
310@@ -1132,6 +1209,9 @@ gvs_tuple_is_normal (GVariantSerialised value)
311 offset = end;
312 }
313
314+ /* All element bounds have been checked above. */
315+ value.ordered_offsets_up_to = G_MAXSIZE;
316+
317 {
318 gsize fixed_size;
319 guint alignment;
320diff --git a/glib/gvariant-serialiser.h b/glib/gvariant-serialiser.h
321index 81343e9..99d18ef 100644
322--- a/glib/gvariant-serialiser.h
323+++ b/glib/gvariant-serialiser.h
324@@ -29,6 +29,14 @@ typedef struct
325 guchar *data;
326 gsize size;
327 gsize depth; /* same semantics as GVariant.depth */
328+ /* If ordered_offsets_up_to == n this means that all the frame offsets up to and
329+ * including the frame offset determining the end of element n are in order.
330+ * This guarantees that the bytes of element n don't overlap with any previous
331+ * element.
332+ *
333+ * This is both read and set by g_variant_serialised_get_child for arrays of
334+ * non-fixed-width types */
335+ gsize ordered_offsets_up_to;
336 } GVariantSerialised;
337
338 /* deserialisation */
339diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
340index 0e5ec8e..967e9a1 100644
341--- a/glib/tests/gvariant.c
342+++ b/glib/tests/gvariant.c
343@@ -1,5 +1,6 @@
344 /*
345 * Copyright © 2010 Codethink Limited
346+ * Copyright © 2020 William Manley
347 *
348 * This library is free software; you can redistribute it and/or
349 * modify it under the terms of the GNU Lesser General Public
350@@ -1283,6 +1284,7 @@ random_instance_filler (GVariantSerialised *serialised,
351 serialised->size = instance->size;
352
353 serialised->depth = 0;
354+ serialised->ordered_offsets_up_to = 0;
355
356 g_assert_true (serialised->type_info == instance->type_info);
357 g_assert_cmpuint (serialised->size, ==, instance->size);
358@@ -5039,6 +5041,47 @@ test_normal_checking_array_offsets (void)
359 g_variant_unref (variant);
360 }
361
362+/* This is a regression test that we can't have non-normal values that take up
363+ * significantly more space than the normal equivalent, by specifying the
364+ * offset table entries so that array elements overlap.
365+ *
366+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_832242 */
367+static void
368+test_normal_checking_array_offsets2 (void)
369+{
370+ const guint8 data[] = {
371+ 'h', 'i', '\0',
372+ 0x03, 0x00, 0x03,
373+ 0x06, 0x00, 0x06,
374+ 0x09, 0x00, 0x09,
375+ 0x0c, 0x00, 0x0c,
376+ 0x0f, 0x00, 0x0f,
377+ 0x12, 0x00, 0x12,
378+ 0x15, 0x00, 0x15,
379+ };
380+ gsize size = sizeof (data);
381+ const GVariantType *aaaaaaas = G_VARIANT_TYPE ("aaaaaaas");
382+ GVariant *variant = NULL;
383+ GVariant *normal_variant = NULL;
384+ GVariant *expected = NULL;
385+
386+ variant = g_variant_new_from_data (aaaaaaas, data, size, FALSE, NULL, NULL);
387+ g_assert_nonnull (variant);
388+
389+ normal_variant = g_variant_get_normal_form (variant);
390+ g_assert_nonnull (normal_variant);
391+ g_assert_cmpuint (g_variant_get_size (normal_variant), <=, size * 2);
392+
393+ expected = g_variant_new_parsed (
394+ "[[[[[[['hi', '', ''], [], []], [], []], [], []], [], []], [], []], [], []]");
395+ g_assert_cmpvariant (expected, variant);
396+ g_assert_cmpvariant (expected, normal_variant);
397+
398+ g_variant_unref (expected);
399+ g_variant_unref (normal_variant);
400+ g_variant_unref (variant);
401+}
402+
403 /* Test that a tuple with invalidly large values in its offset table is
404 * normalised successfully without looping infinitely. */
405 static void
406@@ -5206,6 +5249,8 @@ main (int argc, char **argv)
407 test_normal_checking_tuples);
408 g_test_add_func ("/gvariant/normal-checking/array-offsets",
409 test_normal_checking_array_offsets);
410+ g_test_add_func ("/gvariant/normal-checking/array-offsets2",
411+ test_normal_checking_array_offsets2);
412 g_test_add_func ("/gvariant/normal-checking/tuple-offsets",
413 test_normal_checking_tuple_offsets);
414 g_test_add_func ("/gvariant/normal-checking/empty-object-path",
415--
4162.24.4
417
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0004.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0004.patch
new file mode 100644
index 0000000000..c057729aae
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0004.patch
@@ -0,0 +1,113 @@
1From 345cae9c1aa7bf6752039225ef4c8d8d69fa8d76 Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Fri, 11 Aug 2023 04:09:12 +0000
4Subject: [PATCH] gvariant-serialiser: Factor out code to get bounds of a tuple
5 member
6
7This introduces no functional changes.
8
9Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
10
11Helps: #2121
12
13CVE: CVE-2023-32665
14Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/345cae9c1aa7bf6752039225ef4c8d8d69fa8d76]
15Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
16---
17 glib/gvariant-serialiser.c | 73 ++++++++++++++++++++++++--------------
18 1 file changed, 46 insertions(+), 27 deletions(-)
19
20diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
21index fe0b1a4..6f9b366 100644
22--- a/glib/gvariant-serialiser.c
23+++ b/glib/gvariant-serialiser.c
24@@ -942,6 +942,51 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value)
25 * for the tuple. See the notes in gvarianttypeinfo.h.
26 */
27
28+static void
29+gvs_tuple_get_member_bounds (GVariantSerialised value,
30+ gsize index_,
31+ gsize offset_size,
32+ gsize *out_member_start,
33+ gsize *out_member_end)
34+{
35+ const GVariantMemberInfo *member_info;
36+ gsize member_start, member_end;
37+
38+ member_info = g_variant_type_info_member_info (value.type_info, index_);
39+
40+ if (member_info->i + 1)
41+ member_start = gvs_read_unaligned_le (value.data + value.size -
42+ offset_size * (member_info->i + 1),
43+ offset_size);
44+ else
45+ member_start = 0;
46+
47+ member_start += member_info->a;
48+ member_start &= member_info->b;
49+ member_start |= member_info->c;
50+
51+ if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST)
52+ member_end = value.size - offset_size * (member_info->i + 1);
53+
54+ else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED)
55+ {
56+ gsize fixed_size;
57+
58+ g_variant_type_info_query (member_info->type_info, NULL, &fixed_size);
59+ member_end = member_start + fixed_size;
60+ }
61+
62+ else /* G_VARIANT_MEMBER_ENDING_OFFSET */
63+ member_end = gvs_read_unaligned_le (value.data + value.size -
64+ offset_size * (member_info->i + 2),
65+ offset_size);
66+
67+ if (out_member_start != NULL)
68+ *out_member_start = member_start;
69+ if (out_member_end != NULL)
70+ *out_member_end = member_end;
71+}
72+
73 static gsize
74 gvs_tuple_n_children (GVariantSerialised value)
75 {
76@@ -997,33 +1042,7 @@ gvs_tuple_get_child (GVariantSerialised value,
77 }
78 }
79
80- if (member_info->i + 1)
81- start = gvs_read_unaligned_le (value.data + value.size -
82- offset_size * (member_info->i + 1),
83- offset_size);
84- else
85- start = 0;
86-
87- start += member_info->a;
88- start &= member_info->b;
89- start |= member_info->c;
90-
91- if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST)
92- end = value.size - offset_size * (member_info->i + 1);
93-
94- else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED)
95- {
96- gsize fixed_size;
97-
98- g_variant_type_info_query (child.type_info, NULL, &fixed_size);
99- end = start + fixed_size;
100- child.size = fixed_size;
101- }
102-
103- else /* G_VARIANT_MEMBER_ENDING_OFFSET */
104- end = gvs_read_unaligned_le (value.data + value.size -
105- offset_size * (member_info->i + 2),
106- offset_size);
107+ gvs_tuple_get_member_bounds (value, index_, offset_size, &start, &end);
108
109 /* The child should not extend into the offset table. */
110 if (index_ != g_variant_type_info_n_members (value.type_info) - 1)
111--
1122.24.4
113
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0005.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0005.patch
new file mode 100644
index 0000000000..7e516b07ab
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0005.patch
@@ -0,0 +1,80 @@
1From 73d0aa81c2575a5c9ae77dcb94da919579014fc0 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Fri, 11 Aug 2023 04:13:02 +0000
4Subject: [PATCH] gvariant-serialiser: Rework child size calculation
5
6This reduces a few duplicate calls to `g_variant_type_info_query()` and
7explains why they’re needed.
8
9Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
10
11Helps: #2121
12
13CVE: CVE-2023-32665
14Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/73d0aa81c2575a5c9ae77dcb94da919579014fc0]
15Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
16---
17 glib/gvariant-serialiser.c | 31 +++++++++----------------------
18 1 file changed, 9 insertions(+), 22 deletions(-)
19
20diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
21index 6f9b366..fb75923 100644
22--- a/glib/gvariant-serialiser.c
23+++ b/glib/gvariant-serialiser.c
24@@ -1007,14 +1007,18 @@ gvs_tuple_get_child (GVariantSerialised value,
25 child.depth = value.depth + 1;
26 offset_size = gvs_get_offset_size (value.size);
27
28+ /* Ensure the size is set for fixed-sized children, or
29+ * g_variant_serialised_check() will fail, even if we return
30+ * (child.data == NULL) to indicate an error. */
31+ if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED)
32+ g_variant_type_info_query (child.type_info, NULL, &child.size);
33+
34 /* tuples are the only (potentially) fixed-sized containers, so the
35 * only ones that have to deal with the possibility of having %NULL
36 * data with a non-zero %size if errors occurred elsewhere.
37 */
38 if G_UNLIKELY (value.data == NULL && value.size != 0)
39 {
40- g_variant_type_info_query (child.type_info, NULL, &child.size);
41-
42 /* this can only happen in fixed-sized tuples,
43 * so the child must also be fixed sized.
44 */
45@@ -1032,29 +1036,12 @@ gvs_tuple_get_child (GVariantSerialised value,
46 else
47 {
48 if (offset_size * (member_info->i + 1) > value.size)
49- {
50- /* if the child is fixed size, return its size.
51- * if child is not fixed-sized, return size = 0.
52- */
53- g_variant_type_info_query (child.type_info, NULL, &child.size);
54-
55- return child;
56- }
57+ return child;
58 }
59
60- gvs_tuple_get_member_bounds (value, index_, offset_size, &start, &end);
61-
62 /* The child should not extend into the offset table. */
63- if (index_ != g_variant_type_info_n_members (value.type_info) - 1)
64- {
65- GVariantSerialised last_child;
66- last_child = gvs_tuple_get_child (value,
67- g_variant_type_info_n_members (value.type_info) - 1);
68- last_end = last_child.data + last_child.size - value.data;
69- g_variant_type_info_unref (last_child.type_info);
70- }
71- else
72- last_end = end;
73+ gvs_tuple_get_member_bounds (value, index_, offset_size, &start, &end);
74+ gvs_tuple_get_member_bounds (value, g_variant_type_info_n_members (value.type_info) - 1, offset_size, NULL, &last_end);
75
76 if (start < end && end <= value.size && end <= last_end)
77 {
78--
792.24.4
80
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0006.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0006.patch
new file mode 100644
index 0000000000..8558a7911f
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0006.patch
@@ -0,0 +1,396 @@
1From 7cf6f5b69146d20948d42f0c476688fe17fef787 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Wed, 16 Aug 2023 12:09:06 +0000
4Subject: [PATCH] gvariant: Don't allow child elements of a tuple to overlap
5 each other
6
7This is similar to the earlier commit which prevents child elements of a
8variable-sized array from overlapping each other, but this time for
9tuples. It is based heavily on ideas by William Manley.
10
11Tuples are slightly different from variable-sized arrays in that they
12contain a mixture of fixed and variable sized elements. All but one of
13the variable sized elements have an entry in the frame offsets table.
14This means that if we were to just check the ordering of the frame
15offsets table, the variable sized elements could still overlap
16interleaving fixed sized elements, which would be bad.
17
18Therefore we have to check the elements rather than the frame offsets.
19
20The logic of checking the elements up to the index currently being
21requested, and caching the result in `ordered_offsets_up_to`, means that
22the algorithmic cost implications are the same for this commit as for
23variable-sized arrays: an O(N) cost for these checks is amortised out
24over N accesses to O(1) per access.
25
26Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
27
28Fixes: #2121
29
30CVE: CVE-2023-32665
31Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/7cf6f5b69146d20948d42f0c476688fe17fef787]
32Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
33---
34 glib/gvariant-core.c | 6 +-
35 glib/gvariant-serialiser.c | 40 ++++++++
36 glib/gvariant-serialiser.h | 7 +-
37 glib/gvariant.c | 1 +
38 glib/tests/gvariant.c | 181 +++++++++++++++++++++++++++++++++++++
39 5 files changed, 232 insertions(+), 3 deletions(-)
40
41diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c
42index 9b51e15..b951cd9 100644
43--- a/glib/gvariant-core.c
44+++ b/glib/gvariant-core.c
45@@ -1,6 +1,7 @@
46 /*
47 * Copyright © 2007, 2008 Ryan Lortie
48 * Copyright © 2010 Codethink Limited
49+ * Copyright © 2022 Endless OS Foundation, LLC
50 *
51 * This library is free software; you can redistribute it and/or
52 * modify it under the terms of the GNU Lesser General Public
53@@ -179,7 +180,7 @@ struct _GVariant
54 * offsets themselves.
55 *
56 * This field is only relevant for arrays of non
57- * fixed width types.
58+ * fixed width types and for tuples.
59 *
60 * .tree: Only valid when the instance is in tree form.
61 *
62@@ -1117,6 +1118,9 @@ g_variant_get_child_value (GVariant *value,
63 */
64 s_child = g_variant_serialised_get_child (serialised, index_);
65
66+ /* Update the cached ordered_offsets_up_to, since @serialised will be thrown away when this function exits */
67+ value->contents.serialised.ordered_offsets_up_to = MAX (value->contents.serialised.ordered_offsets_up_to, serialised.ordered_offsets_up_to);
68+
69 /* Check whether this would cause nesting too deep. If so, return a fake
70 * child. The only situation we expect this to happen in is with a variant,
71 * as all other deeply-nested types have a static type, and hence should
72diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
73index fb75923..cd4a3e6 100644
74--- a/glib/gvariant-serialiser.c
75+++ b/glib/gvariant-serialiser.c
76@@ -942,6 +942,10 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value)
77 * for the tuple. See the notes in gvarianttypeinfo.h.
78 */
79
80+/* Note: This doesn’t guarantee that @out_member_end >= @out_member_start; that
81+ * condition may not hold true for invalid serialised variants. The caller is
82+ * responsible for checking the returned values and handling invalid ones
83+ * appropriately. */
84 static void
85 gvs_tuple_get_member_bounds (GVariantSerialised value,
86 gsize index_,
87@@ -1028,6 +1032,42 @@ gvs_tuple_get_child (GVariantSerialised value,
88 return child;
89 }
90
91+ /* If the requested @index_ is beyond the set of indices whose framing offsets
92+ * have been checked, check the remaining offsets to see whether they’re
93+ * normal (in order, no overlapping tuple elements).
94+ *
95+ * Unlike the checks in gvs_variable_sized_array_get_child(), we have to check
96+ * all the tuple *elements* here, not just all the framing offsets, since
97+ * tuples contain a mix of elements which use framing offsets and ones which
98+ * don’t. None of them are allowed to overlap. */
99+ if (index_ > value.ordered_offsets_up_to)
100+ {
101+ gsize i, prev_i_end = 0;
102+
103+ if (value.ordered_offsets_up_to > 0)
104+ gvs_tuple_get_member_bounds (value, value.ordered_offsets_up_to - 1, offset_size, NULL, &prev_i_end);
105+
106+ for (i = value.ordered_offsets_up_to; i <= index_; i++)
107+ {
108+ gsize i_start, i_end;
109+
110+ gvs_tuple_get_member_bounds (value, i, offset_size, &i_start, &i_end);
111+
112+ if (i_start > i_end || i_start < prev_i_end || i_end > value.size)
113+ break;
114+
115+ prev_i_end = i_end;
116+ }
117+
118+ value.ordered_offsets_up_to = i - 1;
119+ }
120+
121+ if (index_ > value.ordered_offsets_up_to)
122+ {
123+ /* Offsets are invalid somewhere, so return an empty child. */
124+ return child;
125+ }
126+
127 if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_OFFSET)
128 {
129 if (offset_size * (member_info->i + 2) > value.size)
130diff --git a/glib/gvariant-serialiser.h b/glib/gvariant-serialiser.h
131index 99d18ef..144aec8 100644
132--- a/glib/gvariant-serialiser.h
133+++ b/glib/gvariant-serialiser.h
134@@ -34,8 +34,11 @@ typedef struct
135 * This guarantees that the bytes of element n don't overlap with any previous
136 * element.
137 *
138- * This is both read and set by g_variant_serialised_get_child for arrays of
139- * non-fixed-width types */
140+ * This is both read and set by g_variant_serialised_get_child() for arrays of
141+ * non-fixed-width types, and for tuples.
142+ *
143+ * Even when dealing with tuples, @ordered_offsets_up_to is an element index,
144+ * rather than an index into the frame offsets. */
145 gsize ordered_offsets_up_to;
146 } GVariantSerialised;
147
148diff --git a/glib/gvariant.c b/glib/gvariant.c
149index d6f68a9..cdb428e 100644
150--- a/glib/gvariant.c
151+++ b/glib/gvariant.c
152@@ -5945,6 +5945,7 @@ g_variant_byteswap (GVariant *value)
153 serialised.type_info = g_variant_get_type_info (trusted);
154 serialised.size = g_variant_get_size (trusted);
155 serialised.data = g_malloc (serialised.size);
156+ serialised.ordered_offsets_up_to = G_MAXSIZE; /* operating on the normal form */
157 g_variant_store (trusted, serialised.data);
158 g_variant_unref (trusted);
159
160diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
161index 967e9a1..a84b02e 100644
162--- a/glib/tests/gvariant.c
163+++ b/glib/tests/gvariant.c
164@@ -1,6 +1,7 @@
165 /*
166 * Copyright © 2010 Codethink Limited
167 * Copyright © 2020 William Manley
168+ * Copyright © 2022 Endless OS Foundation, LLC
169 *
170 * This library is free software; you can redistribute it and/or
171 * modify it under the terms of the GNU Lesser General Public
172@@ -1451,6 +1452,7 @@ test_maybe (void)
173 serialised.data = flavoured_malloc (needed_size, flavour);
174 serialised.size = needed_size;
175 serialised.depth = 0;
176+ serialised.ordered_offsets_up_to = 0;
177
178 g_variant_serialiser_serialise (serialised,
179 random_instance_filler,
180@@ -1574,6 +1576,7 @@ test_array (void)
181 serialised.data = flavoured_malloc (needed_size, flavour);
182 serialised.size = needed_size;
183 serialised.depth = 0;
184+ serialised.ordered_offsets_up_to = 0;
185
186 g_variant_serialiser_serialise (serialised, random_instance_filler,
187 (gpointer *) instances, n_children);
188@@ -1738,6 +1741,7 @@ test_tuple (void)
189 serialised.data = flavoured_malloc (needed_size, flavour);
190 serialised.size = needed_size;
191 serialised.depth = 0;
192+ serialised.ordered_offsets_up_to = 0;
193
194 g_variant_serialiser_serialise (serialised, random_instance_filler,
195 (gpointer *) instances, n_children);
196@@ -1834,6 +1838,7 @@ test_variant (void)
197 serialised.data = flavoured_malloc (needed_size, flavour);
198 serialised.size = needed_size;
199 serialised.depth = 0;
200+ serialised.ordered_offsets_up_to = 0;
201
202 g_variant_serialiser_serialise (serialised, random_instance_filler,
203 (gpointer *) &instance, 1);
204@@ -5106,6 +5111,176 @@ test_normal_checking_tuple_offsets (void)
205 g_variant_unref (variant);
206 }
207
208+/* This is a regression test that we can't have non-normal values that take up
209+ * significantly more space than the normal equivalent, by specifying the
210+ * offset table entries so that tuple elements overlap.
211+ *
212+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_838503 and
213+ * https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_838513 */
214+static void
215+test_normal_checking_tuple_offsets2 (void)
216+{
217+ const GVariantType *data_type = G_VARIANT_TYPE ("(yyaiyyaiyy)");
218+ const guint8 data[] = {
219+ 0x12, 0x34, 0x56, 0x78, 0x01,
220+ /*
221+ ^───────────────────┘
222+
223+ ^^^^^^^^^^ 1st yy
224+ ^^^^^^^^^^ 2nd yy
225+ ^^^^^^^^^^ 3rd yy
226+ ^^^^ Framing offsets
227+ */
228+
229+ /* If this variant was encoded normally, it would be something like this:
230+ * 0x12, 0x34, pad, pad, [array bytes], 0x56, 0x78, pad, pad, [array bytes], 0x9A, 0xBC, 0xXX
231+ * ^─────────────────────────────────────────────────────┘
232+ *
233+ * ^^^^^^^^^^ 1st yy
234+ * ^^^^^^^^^^ 2nd yy
235+ * ^^^^^^^^^^ 3rd yy
236+ * ^^^^ Framing offsets
237+ */
238+ };
239+ gsize size = sizeof (data);
240+ GVariant *variant = NULL;
241+ GVariant *normal_variant = NULL;
242+ GVariant *expected = NULL;
243+
244+ variant = g_variant_new_from_data (data_type, data, size, FALSE, NULL, NULL);
245+ g_assert_nonnull (variant);
246+
247+ normal_variant = g_variant_get_normal_form (variant);
248+ g_assert_nonnull (normal_variant);
249+ g_assert_cmpuint (g_variant_get_size (normal_variant), <=, size * 3);
250+
251+ expected = g_variant_new_parsed (
252+ "@(yyaiyyaiyy) (0x12, 0x34, [], 0x00, 0x00, [], 0x00, 0x00)");
253+ g_assert_cmpvariant (expected, variant);
254+ g_assert_cmpvariant (expected, normal_variant);
255+
256+ g_variant_unref (expected);
257+ g_variant_unref (normal_variant);
258+ g_variant_unref (variant);
259+}
260+
261+/* This is a regression test that overlapping entries in the offset table are
262+ * decoded consistently, even though they’re non-normal.
263+ *
264+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_910935 */
265+static void
266+test_normal_checking_tuple_offsets3 (void)
267+{
268+ /* The expected decoding of this non-normal byte stream is complex. See
269+ * section 2.7.3 (Handling Non-Normal Serialised Data) of the GVariant
270+ * specification.
271+ *
272+ * The rule “Child Values Overlapping Framing Offsets” from the specification
273+ * says that the first `ay` must be decoded as `[0x01]` even though it
274+ * overlaps the first byte of the offset table. However, since commit
275+ * 7eedcd76f7d5b8c98fa60013e1fe6e960bf19df3, GLib explicitly doesn’t allow
276+ * this as it’s exploitable. So the first `ay` must be given a default value.
277+ *
278+ * The second and third `ay`s must be given default values because of rule
279+ * “End Boundary Precedes Start Boundary”.
280+ *
281+ * The `i` must be given a default value because of rule “Start or End
282+ * Boundary of a Child Falls Outside the Container”.
283+ */
284+ const GVariantType *data_type = G_VARIANT_TYPE ("(ayayiay)");
285+ const guint8 data[] = {
286+ 0x01, 0x00, 0x02,
287+ /*
288+ ^──┘
289+
290+ ^^^^^^^^^^ 1st ay, bytes 0-2 (but given a default value anyway, see above)
291+ 2nd ay, bytes 2-0
292+ i, bytes 0-4
293+ 3rd ay, bytes 4-1
294+ ^^^^^^^^^^ Framing offsets
295+ */
296+ };
297+ gsize size = sizeof (data);
298+ GVariant *variant = NULL;
299+ GVariant *normal_variant = NULL;
300+ GVariant *expected = NULL;
301+
302+ variant = g_variant_new_from_data (data_type, data, size, FALSE, NULL, NULL);
303+ g_assert_nonnull (variant);
304+
305+ g_assert_false (g_variant_is_normal_form (variant));
306+
307+ normal_variant = g_variant_get_normal_form (variant);
308+ g_assert_nonnull (normal_variant);
309+ g_assert_cmpuint (g_variant_get_size (normal_variant), <=, size * 3);
310+
311+ expected = g_variant_new_parsed ("@(ayayiay) ([], [], 0, [])");
312+ g_assert_cmpvariant (expected, variant);
313+ g_assert_cmpvariant (expected, normal_variant);
314+
315+ g_variant_unref (expected);
316+ g_variant_unref (normal_variant);
317+ g_variant_unref (variant);
318+}
319+
320+/* This is a regression test that overlapping entries in the offset table are
321+ * decoded consistently, even though they’re non-normal.
322+ *
323+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2121#note_910935 */
324+static void
325+test_normal_checking_tuple_offsets4 (void)
326+{
327+ /* The expected decoding of this non-normal byte stream is complex. See
328+ * section 2.7.3 (Handling Non-Normal Serialised Data) of the GVariant
329+ * specification.
330+ *
331+ * The rule “Child Values Overlapping Framing Offsets” from the specification
332+ * says that the first `ay` must be decoded as `[0x01]` even though it
333+ * overlaps the first byte of the offset table. However, since commit
334+ * 7eedcd76f7d5b8c98fa60013e1fe6e960bf19df3, GLib explicitly doesn’t allow
335+ * this as it’s exploitable. So the first `ay` must be given a default value.
336+ *
337+ * The second `ay` must be given a default value because of rule “End Boundary
338+ * Precedes Start Boundary”.
339+ *
340+ * The third `ay` must be given a default value because its framing offsets
341+ * overlap that of the first `ay`.
342+ */
343+ const GVariantType *data_type = G_VARIANT_TYPE ("(ayayay)");
344+ const guint8 data[] = {
345+ 0x01, 0x00, 0x02,
346+ /*
347+ ^──┘
348+
349+ ^^^^^^^^^^ 1st ay, bytes 0-2 (but given a default value anyway, see above)
350+ 2nd ay, bytes 2-0
351+ 3rd ay, bytes 0-1
352+ ^^^^^^^^^^ Framing offsets
353+ */
354+ };
355+ gsize size = sizeof (data);
356+ GVariant *variant = NULL;
357+ GVariant *normal_variant = NULL;
358+ GVariant *expected = NULL;
359+
360+ variant = g_variant_new_from_data (data_type, data, size, FALSE, NULL, NULL);
361+ g_assert_nonnull (variant);
362+
363+ g_assert_false (g_variant_is_normal_form (variant));
364+
365+ normal_variant = g_variant_get_normal_form (variant);
366+ g_assert_nonnull (normal_variant);
367+ g_assert_cmpuint (g_variant_get_size (normal_variant), <=, size * 3);
368+
369+ expected = g_variant_new_parsed ("@(ayayay) ([], [], [])");
370+ g_assert_cmpvariant (expected, variant);
371+ g_assert_cmpvariant (expected, normal_variant);
372+
373+ g_variant_unref (expected);
374+ g_variant_unref (normal_variant);
375+ g_variant_unref (variant);
376+}
377+
378 /* Test that an empty object path is normalised successfully to the base object
379 * path, ‘/’. */
380 static void
381@@ -5253,6 +5428,12 @@ main (int argc, char **argv)
382 test_normal_checking_array_offsets2);
383 g_test_add_func ("/gvariant/normal-checking/tuple-offsets",
384 test_normal_checking_tuple_offsets);
385+ g_test_add_func ("/gvariant/normal-checking/tuple-offsets2",
386+ test_normal_checking_tuple_offsets2);
387+ g_test_add_func ("/gvariant/normal-checking/tuple-offsets3",
388+ test_normal_checking_tuple_offsets3);
389+ g_test_add_func ("/gvariant/normal-checking/tuple-offsets4",
390+ test_normal_checking_tuple_offsets4);
391 g_test_add_func ("/gvariant/normal-checking/empty-object-path",
392 test_normal_checking_empty_object_path);
393
394--
3952.24.4
396
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0007.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0007.patch
new file mode 100644
index 0000000000..83d0205160
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0007.patch
@@ -0,0 +1,49 @@
1From e6490c84e84ba9f182fbd83b51ff4f9f5a0a1793 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Wed, 16 Aug 2023 03:42:47 +0000
4Subject: [PATCH] gvariant: Port g_variant_deep_copy() to count its iterations
5 directly
6
7This is equivalent to what `GVariantIter` does, but it means that
8`g_variant_deep_copy()` is making its own `g_variant_get_child_value()`
9calls.
10
11This will be useful in an upcoming commit, where those child values will
12be inspected a little more deeply.
13
14Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
15
16Helps: #2121
17
18CVE: CVE-2023-32665
19Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/e6490c84e84ba9f182fbd83b51ff4f9f5a0a1793]
20Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
21---
22 glib/gvariant.c | 7 +++----
23 1 file changed, 3 insertions(+), 4 deletions(-)
24
25diff --git a/glib/gvariant.c b/glib/gvariant.c
26index cdb428e..fdd36be 100644
27--- a/glib/gvariant.c
28+++ b/glib/gvariant.c
29@@ -5799,14 +5799,13 @@ g_variant_deep_copy (GVariant *value)
30 case G_VARIANT_CLASS_VARIANT:
31 {
32 GVariantBuilder builder;
33- GVariantIter iter;
34- GVariant *child;
35+ gsize i, n_children;
36
37 g_variant_builder_init (&builder, g_variant_get_type (value));
38- g_variant_iter_init (&iter, value);
39
40- while ((child = g_variant_iter_next_value (&iter)))
41+ for (i = 0, n_children = g_variant_n_children (value); i < n_children; i++)
42 {
43+ GVariant *child = g_variant_get_child_value (value, i);
44 g_variant_builder_add_value (&builder, g_variant_deep_copy (child));
45 g_variant_unref (child);
46 }
47--
482.24.4
49
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0008.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0008.patch
new file mode 100644
index 0000000000..f098548618
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0008.patch
@@ -0,0 +1,394 @@
1From d1a293c4e29880b8d17bb826c9a426a440ca4a91 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Thu, 17 Aug 2023 01:30:38 +0000
4Subject: [PATCH] gvariant: Track checked and ordered offsets independently
5
6The past few commits introduced the concept of known-good offsets in the
7offset table (which is used for variable-width arrays and tuples).
8Good offsets are ones which are non-overlapping with all the previous
9offsets in the table.
10
11If a bad offset is encountered when indexing into the array or tuple,
12the cached known-good offset index will not be increased. In this way,
13all child variants at and beyond the first bad offset can be returned as
14default values rather than dereferencing potentially invalid data.
15
16In this case, there was no information about the fact that the indexes
17between the highest known-good index and the requested one had been
18checked already. That could lead to a pathological case where an offset
19table with an invalid first offset is repeatedly checked in full when
20trying to access higher-indexed children.
21
22Avoid that by storing the index of the highest checked offset in the
23table, as well as the index of the highest good/ordered offset.
24
25Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
26
27Helps: #2121
28
29CVE: CVE-2023-32665
30Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/d1a293c4e29880b8d17bb826c9a426a440ca4a91]
31Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
32---
33 glib/gvariant-core.c | 28 ++++++++++++++++++++++++
34 glib/gvariant-serialiser.c | 44 +++++++++++++++++++++++++++-----------
35 glib/gvariant-serialiser.h | 9 ++++++++
36 glib/gvariant.c | 1 +
37 glib/tests/gvariant.c | 5 +++++
38 5 files changed, 75 insertions(+), 12 deletions(-)
39
40diff --git a/glib/gvariant-core.c b/glib/gvariant-core.c
41index b951cd9..1b9d5cc 100644
42--- a/glib/gvariant-core.c
43+++ b/glib/gvariant-core.c
44@@ -67,6 +67,7 @@ struct _GVariant
45 GBytes *bytes;
46 gconstpointer data;
47 gsize ordered_offsets_up_to;
48+ gsize checked_offsets_up_to;
49 } serialised;
50
51 struct
52@@ -182,6 +183,24 @@ struct _GVariant
53 * This field is only relevant for arrays of non
54 * fixed width types and for tuples.
55 *
56+ * .checked_offsets_up_to: Similarly to .ordered_offsets_up_to, this stores
57+ * the index of the highest element, n, whose frame
58+ * offsets (and all the preceding frame offsets)
59+ * have been checked for validity.
60+ *
61+ * It is always the case that
62+ * .checked_offsets_up_to ≥ .ordered_offsets_up_to.
63+ *
64+ * If .checked_offsets_up_to == .ordered_offsets_up_to,
65+ * then a bad offset has not been found so far.
66+ *
67+ * If .checked_offsets_up_to > .ordered_offsets_up_to,
68+ * then a bad offset has been found at
69+ * (.ordered_offsets_up_to + 1).
70+ *
71+ * This field is only relevant for arrays of non
72+ * fixed width types and for tuples.
73+ *
74 * .tree: Only valid when the instance is in tree form.
75 *
76 * Note that accesses from other threads could result in
77@@ -386,6 +405,7 @@ g_variant_to_serialised (GVariant *value)
78 value->size,
79 value->depth,
80 value->contents.serialised.ordered_offsets_up_to,
81+ value->contents.serialised.checked_offsets_up_to,
82 };
83 return serialised;
84 }
85@@ -418,6 +438,7 @@ g_variant_serialise (GVariant *value,
86 serialised.data = data;
87 serialised.depth = value->depth;
88 serialised.ordered_offsets_up_to = 0;
89+ serialised.checked_offsets_up_to = 0;
90
91 children = (gpointer *) value->contents.tree.children;
92 n_children = value->contents.tree.n_children;
93@@ -464,10 +485,12 @@ g_variant_fill_gvs (GVariantSerialised *serialised,
94 if (value->state & STATE_SERIALISED)
95 {
96 serialised->ordered_offsets_up_to = value->contents.serialised.ordered_offsets_up_to;
97+ serialised->checked_offsets_up_to = value->contents.serialised.checked_offsets_up_to;
98 }
99 else
100 {
101 serialised->ordered_offsets_up_to = 0;
102+ serialised->checked_offsets_up_to = 0;
103 }
104
105 if (serialised->data)
106@@ -513,6 +536,7 @@ g_variant_ensure_serialised (GVariant *value)
107 value->contents.serialised.data = g_bytes_get_data (bytes, NULL);
108 value->contents.serialised.bytes = bytes;
109 value->contents.serialised.ordered_offsets_up_to = G_MAXSIZE;
110+ value->contents.serialised.checked_offsets_up_to = G_MAXSIZE;
111 value->state |= STATE_SERIALISED;
112 }
113 }
114@@ -594,6 +618,7 @@ g_variant_new_from_bytes (const GVariantType *type,
115 serialised.data = (guchar *) g_bytes_get_data (bytes, &serialised.size);
116 serialised.depth = 0;
117 serialised.ordered_offsets_up_to = trusted ? G_MAXSIZE : 0;
118+ serialised.checked_offsets_up_to = trusted ? G_MAXSIZE : 0;
119
120 if (!g_variant_serialised_check (serialised))
121 {
122@@ -644,6 +669,7 @@ g_variant_new_from_bytes (const GVariantType *type,
123 }
124
125 value->contents.serialised.ordered_offsets_up_to = trusted ? G_MAXSIZE : 0;
126+ value->contents.serialised.checked_offsets_up_to = trusted ? G_MAXSIZE : 0;
127
128 g_clear_pointer (&owned_bytes, g_bytes_unref);
129
130@@ -1120,6 +1146,7 @@ g_variant_get_child_value (GVariant *value,
131
132 /* Update the cached ordered_offsets_up_to, since @serialised will be thrown away when this function exits */
133 value->contents.serialised.ordered_offsets_up_to = MAX (value->contents.serialised.ordered_offsets_up_to, serialised.ordered_offsets_up_to);
134+ value->contents.serialised.checked_offsets_up_to = MAX (value->contents.serialised.checked_offsets_up_to, serialised.checked_offsets_up_to);
135
136 /* Check whether this would cause nesting too deep. If so, return a fake
137 * child. The only situation we expect this to happen in is with a variant,
138@@ -1147,6 +1174,7 @@ g_variant_get_child_value (GVariant *value,
139 g_bytes_ref (value->contents.serialised.bytes);
140 child->contents.serialised.data = s_child.data;
141 child->contents.serialised.ordered_offsets_up_to = s_child.ordered_offsets_up_to;
142+ child->contents.serialised.checked_offsets_up_to = s_child.checked_offsets_up_to;
143
144 return child;
145 }
146diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c
147index cd4a3e6..0bf7243 100644
148--- a/glib/gvariant-serialiser.c
149+++ b/glib/gvariant-serialiser.c
150@@ -120,6 +120,8 @@
151 *
152 * @depth has no restrictions; the depth of a top-level serialised #GVariant is
153 * zero, and it increases for each level of nested child.
154+ *
155+ * @checked_offsets_up_to is always ≥ @ordered_offsets_up_to
156 */
157
158 /* < private >
159@@ -147,6 +149,9 @@ g_variant_serialised_check (GVariantSerialised serialised)
160 !(serialised.size == 0 || serialised.data != NULL))
161 return FALSE;
162
163+ if (serialised.ordered_offsets_up_to > serialised.checked_offsets_up_to)
164+ return FALSE;
165+
166 /* Depending on the native alignment requirements of the machine, the
167 * compiler will insert either 3 or 7 padding bytes after the char.
168 * This will result in the sizeof() the struct being 12 or 16.
169@@ -266,6 +271,7 @@ gvs_fixed_sized_maybe_get_child (GVariantSerialised value,
170 g_variant_type_info_ref (value.type_info);
171 value.depth++;
172 value.ordered_offsets_up_to = 0;
173+ value.checked_offsets_up_to = 0;
174
175 return value;
176 }
177@@ -297,7 +303,7 @@ gvs_fixed_sized_maybe_serialise (GVariantSerialised value,
178 {
179 if (n_children)
180 {
181- GVariantSerialised child = { NULL, value.data, value.size, value.depth + 1, 0 };
182+ GVariantSerialised child = { NULL, value.data, value.size, value.depth + 1, 0, 0 };
183
184 gvs_filler (&child, children[0]);
185 }
186@@ -320,6 +326,7 @@ gvs_fixed_sized_maybe_is_normal (GVariantSerialised value)
187 value.type_info = g_variant_type_info_element (value.type_info);
188 value.depth++;
189 value.ordered_offsets_up_to = 0;
190+ value.checked_offsets_up_to = 0;
191
192 return g_variant_serialised_is_normal (value);
193 }
194@@ -362,6 +369,7 @@ gvs_variable_sized_maybe_get_child (GVariantSerialised value,
195
196 value.depth++;
197 value.ordered_offsets_up_to = 0;
198+ value.checked_offsets_up_to = 0;
199
200 return value;
201 }
202@@ -392,7 +400,7 @@ gvs_variable_sized_maybe_serialise (GVariantSerialised value,
203 {
204 if (n_children)
205 {
206- GVariantSerialised child = { NULL, value.data, value.size - 1, value.depth + 1, 0 };
207+ GVariantSerialised child = { NULL, value.data, value.size - 1, value.depth + 1, 0, 0 };
208
209 /* write the data for the child. */
210 gvs_filler (&child, children[0]);
211@@ -413,6 +421,7 @@ gvs_variable_sized_maybe_is_normal (GVariantSerialised value)
212 value.size--;
213 value.depth++;
214 value.ordered_offsets_up_to = 0;
215+ value.checked_offsets_up_to = 0;
216
217 return g_variant_serialised_is_normal (value);
218 }
219@@ -739,39 +748,46 @@ gvs_variable_sized_array_get_child (GVariantSerialised value,
220
221 /* If the requested @index_ is beyond the set of indices whose framing offsets
222 * have been checked, check the remaining offsets to see whether they’re
223- * normal (in order, no overlapping array elements). */
224- if (index_ > value.ordered_offsets_up_to)
225+ * normal (in order, no overlapping array elements).
226+ *
227+ * Don’t bother checking if the highest known-good offset is lower than the
228+ * highest checked offset, as that means there’s an invalid element at that
229+ * index, so there’s no need to check further. */
230+ if (index_ > value.checked_offsets_up_to &&
231+ value.ordered_offsets_up_to == value.checked_offsets_up_to)
232 {
233 switch (offsets.offset_size)
234 {
235 case 1:
236 {
237 value.ordered_offsets_up_to = find_unordered_guint8 (
238- offsets.array, value.ordered_offsets_up_to, index_ + 1);
239+ offsets.array, value.checked_offsets_up_to, index_ + 1);
240 break;
241 }
242 case 2:
243 {
244 value.ordered_offsets_up_to = find_unordered_guint16 (
245- offsets.array, value.ordered_offsets_up_to, index_ + 1);
246+ offsets.array, value.checked_offsets_up_to, index_ + 1);
247 break;
248 }
249 case 4:
250 {
251 value.ordered_offsets_up_to = find_unordered_guint32 (
252- offsets.array, value.ordered_offsets_up_to, index_ + 1);
253+ offsets.array, value.checked_offsets_up_to, index_ + 1);
254 break;
255 }
256 case 8:
257 {
258 value.ordered_offsets_up_to = find_unordered_guint64 (
259- offsets.array, value.ordered_offsets_up_to, index_ + 1);
260+ offsets.array, value.checked_offsets_up_to, index_ + 1);
261 break;
262 }
263 default:
264 /* gvs_get_offset_size() only returns maximum 8 */
265 g_assert_not_reached ();
266 }
267+
268+ value.checked_offsets_up_to = index_;
269 }
270
271 if (index_ > value.ordered_offsets_up_to)
272@@ -916,6 +932,7 @@ gvs_variable_sized_array_is_normal (GVariantSerialised value)
273
274 /* All offsets have now been checked. */
275 value.ordered_offsets_up_to = G_MAXSIZE;
276+ value.checked_offsets_up_to = G_MAXSIZE;
277
278 return TRUE;
279 }
280@@ -1040,14 +1057,15 @@ gvs_tuple_get_child (GVariantSerialised value,
281 * all the tuple *elements* here, not just all the framing offsets, since
282 * tuples contain a mix of elements which use framing offsets and ones which
283 * don’t. None of them are allowed to overlap. */
284- if (index_ > value.ordered_offsets_up_to)
285+ if (index_ > value.checked_offsets_up_to &&
286+ value.ordered_offsets_up_to == value.checked_offsets_up_to)
287 {
288 gsize i, prev_i_end = 0;
289
290- if (value.ordered_offsets_up_to > 0)
291- gvs_tuple_get_member_bounds (value, value.ordered_offsets_up_to - 1, offset_size, NULL, &prev_i_end);
292+ if (value.checked_offsets_up_to > 0)
293+ gvs_tuple_get_member_bounds (value, value.checked_offsets_up_to - 1, offset_size, NULL, &prev_i_end);
294
295- for (i = value.ordered_offsets_up_to; i <= index_; i++)
296+ for (i = value.checked_offsets_up_to; i <= index_; i++)
297 {
298 gsize i_start, i_end;
299
300@@ -1060,6 +1078,7 @@ gvs_tuple_get_child (GVariantSerialised value,
301 }
302
303 value.ordered_offsets_up_to = i - 1;
304+ value.checked_offsets_up_to = index_;
305 }
306
307 if (index_ > value.ordered_offsets_up_to)
308@@ -1257,6 +1276,7 @@ gvs_tuple_is_normal (GVariantSerialised value)
309
310 /* All element bounds have been checked above. */
311 value.ordered_offsets_up_to = G_MAXSIZE;
312+ value.checked_offsets_up_to = G_MAXSIZE;
313
314 {
315 gsize fixed_size;
316diff --git a/glib/gvariant-serialiser.h b/glib/gvariant-serialiser.h
317index 144aec8..e132451 100644
318--- a/glib/gvariant-serialiser.h
319+++ b/glib/gvariant-serialiser.h
320@@ -40,6 +40,15 @@ typedef struct
321 * Even when dealing with tuples, @ordered_offsets_up_to is an element index,
322 * rather than an index into the frame offsets. */
323 gsize ordered_offsets_up_to;
324+
325+ /* Similar to @ordered_offsets_up_to. This gives the index of the child element
326+ * whose frame offset is the highest in the offset table which has been
327+ * checked so far.
328+ *
329+ * This is always ≥ @ordered_offsets_up_to. It is always an element index.
330+ *
331+ * See documentation in gvariant-core.c for `struct GVariant` for details. */
332+ gsize checked_offsets_up_to;
333 } GVariantSerialised;
334
335 /* deserialisation */
336diff --git a/glib/gvariant.c b/glib/gvariant.c
337index fdd36be..f910bd4 100644
338--- a/glib/gvariant.c
339+++ b/glib/gvariant.c
340@@ -5945,6 +5945,7 @@ g_variant_byteswap (GVariant *value)
341 serialised.size = g_variant_get_size (trusted);
342 serialised.data = g_malloc (serialised.size);
343 serialised.ordered_offsets_up_to = G_MAXSIZE; /* operating on the normal form */
344+ serialised.checked_offsets_up_to = G_MAXSIZE;
345 g_variant_store (trusted, serialised.data);
346 g_variant_unref (trusted);
347
348diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
349index a84b02e..640f3c0 100644
350--- a/glib/tests/gvariant.c
351+++ b/glib/tests/gvariant.c
352@@ -1286,6 +1286,7 @@ random_instance_filler (GVariantSerialised *serialised,
353
354 serialised->depth = 0;
355 serialised->ordered_offsets_up_to = 0;
356+ serialised->checked_offsets_up_to = 0;
357
358 g_assert_true (serialised->type_info == instance->type_info);
359 g_assert_cmpuint (serialised->size, ==, instance->size);
360@@ -1453,6 +1454,7 @@ test_maybe (void)
361 serialised.size = needed_size;
362 serialised.depth = 0;
363 serialised.ordered_offsets_up_to = 0;
364+ serialised.checked_offsets_up_to = 0;
365
366 g_variant_serialiser_serialise (serialised,
367 random_instance_filler,
368@@ -1577,6 +1579,7 @@ test_array (void)
369 serialised.size = needed_size;
370 serialised.depth = 0;
371 serialised.ordered_offsets_up_to = 0;
372+ serialised.checked_offsets_up_to = 0;
373
374 g_variant_serialiser_serialise (serialised, random_instance_filler,
375 (gpointer *) instances, n_children);
376@@ -1742,6 +1745,7 @@ test_tuple (void)
377 serialised.size = needed_size;
378 serialised.depth = 0;
379 serialised.ordered_offsets_up_to = 0;
380+ serialised.checked_offsets_up_to = 0;
381
382 g_variant_serialiser_serialise (serialised, random_instance_filler,
383 (gpointer *) instances, n_children);
384@@ -1839,6 +1843,7 @@ test_variant (void)
385 serialised.size = needed_size;
386 serialised.depth = 0;
387 serialised.ordered_offsets_up_to = 0;
388+ serialised.checked_offsets_up_to = 0;
389
390 g_variant_serialiser_serialise (serialised, random_instance_filler,
391 (gpointer *) &instance, 1);
392--
3932.24.4
394
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0009.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0009.patch
new file mode 100644
index 0000000000..a523e60b91
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32665-0009.patch
@@ -0,0 +1,97 @@
1From 298a537d5f6783e55d87e40011ee3fd3b22b72f9 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Thu, 17 Aug 2023 01:39:01 +0000
4Subject: [PATCH] gvariant: Zero-initialise various GVariantSerialised objects
5
6The following few commits will add a couple of new fields to
7`GVariantSerialised`, and they should be zero-filled by default.
8
9Try and pre-empt that a bit by zero-filling `GVariantSerialised` by
10default in a few places.
11
12Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
13
14Helps: #2121
15
16CVE: CVE-2023-32665
17Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/glib/-/commit/298a537d5f6783e55d87e40011ee3fd3b22b72f9]
18Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
19---
20 glib/gvariant.c | 2 +-
21 glib/tests/gvariant.c | 12 ++++++------
22 2 files changed, 7 insertions(+), 7 deletions(-)
23
24diff --git a/glib/gvariant.c b/glib/gvariant.c
25index f910bd4..8ba701e 100644
26--- a/glib/gvariant.c
27+++ b/glib/gvariant.c
28@@ -5936,7 +5936,7 @@ g_variant_byteswap (GVariant *value)
29 if (alignment)
30 /* (potentially) contains multi-byte numeric data */
31 {
32- GVariantSerialised serialised;
33+ GVariantSerialised serialised = { 0, };
34 GVariant *trusted;
35 GBytes *bytes;
36
37diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c
38index 640f3c0..d640c81 100644
39--- a/glib/tests/gvariant.c
40+++ b/glib/tests/gvariant.c
41@@ -1446,7 +1446,7 @@ test_maybe (void)
42
43 for (flavour = 0; flavour < 8; flavour += alignment)
44 {
45- GVariantSerialised serialised;
46+ GVariantSerialised serialised = { 0, };
47 GVariantSerialised child;
48
49 serialised.type_info = type_info;
50@@ -1572,7 +1572,7 @@ test_array (void)
51
52 for (flavour = 0; flavour < 8; flavour += alignment)
53 {
54- GVariantSerialised serialised;
55+ GVariantSerialised serialised = { 0, };
56
57 serialised.type_info = array_info;
58 serialised.data = flavoured_malloc (needed_size, flavour);
59@@ -1738,7 +1738,7 @@ test_tuple (void)
60
61 for (flavour = 0; flavour < 8; flavour += alignment)
62 {
63- GVariantSerialised serialised;
64+ GVariantSerialised serialised = { 0, };
65
66 serialised.type_info = type_info;
67 serialised.data = flavoured_malloc (needed_size, flavour);
68@@ -1835,7 +1835,7 @@ test_variant (void)
69
70 for (flavour = 0; flavour < 8; flavour += alignment)
71 {
72- GVariantSerialised serialised;
73+ GVariantSerialised serialised = { 0, };
74 GVariantSerialised child;
75
76 serialised.type_info = type_info;
77@@ -2284,7 +2284,7 @@ serialise_tree (TreeInstance *tree,
78 static void
79 test_byteswap (void)
80 {
81- GVariantSerialised one, two;
82+ GVariantSerialised one = { 0, }, two = { 0, };
83 TreeInstance *tree;
84
85 tree = tree_instance_new (NULL, 3);
86@@ -2358,7 +2358,7 @@ test_serialiser_children (void)
87 static void
88 test_fuzz (gdouble *fuzziness)
89 {
90- GVariantSerialised serialised;
91+ GVariantSerialised serialised = { 0, };
92 TreeInstance *tree;
93
94 /* make an instance */
95--
962.24.4
97
diff --git a/meta/recipes-core/glib-2.0/glib-2.0_2.62.6.bb b/meta/recipes-core/glib-2.0/glib-2.0_2.62.6.bb
index c2145bc6c2..60a6b843c1 100644
--- a/meta/recipes-core/glib-2.0/glib-2.0_2.62.6.bb
+++ b/meta/recipes-core/glib-2.0/glib-2.0_2.62.6.bb
@@ -42,6 +42,20 @@ SRC_URI = "${GNOME_MIRROR}/glib/${SHRT_VER}/glib-${PV}.tar.xz \
42 file://CVE-2021-28153-3.patch \ 42 file://CVE-2021-28153-3.patch \
43 file://CVE-2021-28153-4.patch \ 43 file://CVE-2021-28153-4.patch \
44 file://CVE-2021-28153-5.patch \ 44 file://CVE-2021-28153-5.patch \
45 file://CVE-2023-32665-0001.patch \
46 file://CVE-2023-32665-0002.patch \
47 file://CVE-2023-32665-0003.patch \
48 file://CVE-2023-32665-0004.patch \
49 file://CVE-2023-32665-0005.patch \
50 file://CVE-2023-32665-0006.patch \
51 file://CVE-2023-32665-0007.patch \
52 file://CVE-2023-32665-0008.patch \
53 file://CVE-2023-32665-0009.patch \
54 file://CVE-2023-29499.patch \
55 file://CVE-2023-32611-0001.patch \
56 file://CVE-2023-32611-0002.patch \
57 file://CVE-2023-32643.patch \
58 file://CVE-2023-32636.patch \
45 " 59 "
46 60
47SRC_URI_append_class-native = " file://relocate-modules.patch" 61SRC_URI_append_class-native = " file://relocate-modules.patch"