summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32611-0002.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32611-0002.patch')
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2023-32611-0002.patch255
1 files changed, 255 insertions, 0 deletions
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