summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/glib-2.0
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/glib-2.0')
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27218.patch129
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-01.patch170
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-02.patch249
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-03.patch131
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-04.patch298
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-05.patch54
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-06.patch101
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-07.patch76
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-08.patch101
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-09.patch100
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-10.patch59
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-11.patch63
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-1.patch36
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-2.patch38
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-4.patch38
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-5.patch100
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg2-1.patch49
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg2-2.patch43
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg2-3.patch232
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-1.patch27
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-2.patch42
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-3.patch57
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-4.patch265
-rw-r--r--meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-5.patch55
-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.bb38
-rw-r--r--meta/recipes-core/glib-2.0/glib.inc2
40 files changed, 5248 insertions, 1 deletions
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27218.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27218.patch
new file mode 100644
index 0000000000..6257763d8d
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27218.patch
@@ -0,0 +1,129 @@
1Backport of:
2
3From 0f384c88a241bbbd884487b1c40b7b75f1e638d3 Mon Sep 17 00:00:00 2001
4From: Krzesimir Nowak <qdlacz@gmail.com>
5Date: Wed, 10 Feb 2021 23:51:07 +0100
6Subject: [PATCH] gbytearray: Do not accept too large byte arrays
7
8GByteArray uses guint for storing the length of the byte array, but it
9also has a constructor (g_byte_array_new_take) that takes length as a
10gsize. gsize may be larger than guint (64 bits for gsize vs 32 bits
11for guint). It is possible to call the function with a value greater
12than G_MAXUINT, which will result in silent length truncation. This
13may happen as a result of unreffing GBytes into GByteArray, so rather
14be loud about it.
15
16(Test case tweaked by Philip Withnall.)
17
18(Backport 2.66: Add #include gstrfuncsprivate.h in the test case for
19`g_memdup2()`.)
20
21Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
22CVE: CVE-2021-27218
23Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
24Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
25
26---
27 glib/garray.c | 6 ++++++
28 glib/gbytes.c | 4 ++++
29 glib/tests/bytes.c | 35 ++++++++++++++++++++++++++++++++++-
30 3 files changed, 44 insertions(+), 1 deletion(-)
31
32--- a/glib/garray.c
33+++ b/glib/garray.c
34@@ -2234,6 +2234,10 @@ g_byte_array_steal (GByteArray *array,
35 * Create byte array containing the data. The data will be owned by the array
36 * and will be freed with g_free(), i.e. it could be allocated using g_strdup().
37 *
38+ * Do not use it if @len is greater than %G_MAXUINT. #GByteArray
39+ * stores the length of its data in #guint, which may be shorter than
40+ * #gsize.
41+ *
42 * Since: 2.32
43 *
44 * Returns: (transfer full): a new #GByteArray
45@@ -2245,6 +2249,8 @@ g_byte_array_new_take (guint8 *data,
46 GByteArray *array;
47 GRealArray *real;
48
49+ g_return_val_if_fail (len <= G_MAXUINT, NULL);
50+
51 array = g_byte_array_new ();
52 real = (GRealArray *)array;
53 g_assert (real->data == NULL);
54--- a/glib/gbytes.c
55+++ b/glib/gbytes.c
56@@ -519,6 +519,10 @@ g_bytes_unref_to_data (GBytes *bytes,
57 * g_bytes_new(), g_bytes_new_take() or g_byte_array_free_to_bytes(). In all
58 * other cases the data is copied.
59 *
60+ * Do not use it if @bytes contains more than %G_MAXUINT
61+ * bytes. #GByteArray stores the length of its data in #guint, which
62+ * may be shorter than #gsize, that @bytes is using.
63+ *
64 * Returns: (transfer full): a new mutable #GByteArray containing the same byte data
65 *
66 * Since: 2.32
67--- a/glib/tests/bytes.c
68+++ b/glib/tests/bytes.c
69@@ -10,12 +10,12 @@
70 */
71
72 #undef G_DISABLE_ASSERT
73-#undef G_LOG_DOMAIN
74
75 #include <stdio.h>
76 #include <stdlib.h>
77 #include <string.h>
78 #include "glib.h"
79+#include "glib/gstrfuncsprivate.h"
80
81 /* Keep in sync with glib/gbytes.c */
82 struct _GBytes
83@@ -334,6 +334,38 @@ test_to_array_transferred (void)
84 }
85
86 static void
87+test_to_array_transferred_oversize (void)
88+{
89+ g_test_message ("g_bytes_unref_to_array() can only take GBytes up to "
90+ "G_MAXUINT in length; test that longer ones are rejected");
91+
92+ if (sizeof (guint) >= sizeof (gsize))
93+ {
94+ g_test_skip ("Skipping test as guint is not smaller than gsize");
95+ }
96+ else if (g_test_undefined ())
97+ {
98+ GByteArray *array = NULL;
99+ GBytes *bytes = NULL;
100+ gpointer data = g_memdup2 (NYAN, N_NYAN);
101+ gsize len = ((gsize) G_MAXUINT) + 1;
102+
103+ bytes = g_bytes_new_take (data, len);
104+ g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
105+ "g_byte_array_new_take: assertion 'len <= G_MAXUINT' failed");
106+ array = g_bytes_unref_to_array (g_steal_pointer (&bytes));
107+ g_test_assert_expected_messages ();
108+ g_assert_null (array);
109+
110+ g_free (data);
111+ }
112+ else
113+ {
114+ g_test_skip ("Skipping test as testing undefined behaviour is disabled");
115+ }
116+}
117+
118+static void
119 test_to_array_two_refs (void)
120 {
121 gconstpointer memory;
122@@ -410,6 +442,7 @@ main (int argc, char *argv[])
123 g_test_add_func ("/bytes/to-array/transfered", test_to_array_transferred);
124 g_test_add_func ("/bytes/to-array/two-refs", test_to_array_two_refs);
125 g_test_add_func ("/bytes/to-array/non-malloc", test_to_array_non_malloc);
126+ g_test_add_func ("/bytes/to-array/transferred/oversize", test_to_array_transferred_oversize);
127 g_test_add_func ("/bytes/null", test_null);
128
129 return g_test_run ();
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-01.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-01.patch
new file mode 100644
index 0000000000..2af9dd6aa4
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-01.patch
@@ -0,0 +1,170 @@
1Backport of:
2
3From 5e5f75a77e399c638be66d74e5daa8caeb433e00 Mon Sep 17 00:00:00 2001
4From: Philip Withnall <pwithnall@endlessos.org>
5Date: Thu, 4 Feb 2021 13:30:52 +0000
6Subject: [PATCH 01/11] gstrfuncs: Add internal g_memdup2() function
7MIME-Version: 1.0
8Content-Type: text/plain; charset=UTF-8
9Content-Transfer-Encoding: 8bit
10
11This will replace the existing `g_memdup()` function for use within
12GLib. It has an unavoidable security flaw of taking its `byte_size`
13argument as a `guint` rather than as a `gsize`. Most callers will
14expect it to be a `gsize`, and may pass in large values which could
15silently be truncated, resulting in an undersize allocation compared
16to what the caller expects.
17
18This could lead to a classic buffer overflow vulnerability for many
19callers of `g_memdup()`.
20
21`g_memdup2()`, in comparison, takes its `byte_size` as a `gsize`.
22
23Spotted by Kevin Backhouse of GHSL.
24
25In GLib 2.68, `g_memdup2()` will be a new public API. In this version
26for backport to older stable releases, it’s a new `static inline` API
27in a private header, so that use of `g_memdup()` within GLib can be
28fixed without adding a new API in a stable release series.
29
30Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
31Helps: GHSL-2021-045
32Helps: #2319
33
34Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
35CVE: CVE-2021-27219
36Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
37Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
38
39---
40 docs/reference/glib/meson.build | 1 +
41 glib/gstrfuncsprivate.h | 55 +++++++++++++++++++++++++++++++++
42 glib/meson.build | 1 +
43 glib/tests/strfuncs.c | 23 ++++++++++++++
44 4 files changed, 80 insertions(+)
45 create mode 100644 glib/gstrfuncsprivate.h
46
47--- a/docs/reference/glib/meson.build
48+++ b/docs/reference/glib/meson.build
49@@ -22,6 +22,7 @@ if get_option('gtk_doc')
50 'gprintfint.h',
51 'gmirroringtable.h',
52 'gscripttable.h',
53+ 'gstrfuncsprivate.h',
54 'glib-mirroring-tab',
55 'gnulib',
56 'pcre',
57--- /dev/null
58+++ b/glib/gstrfuncsprivate.h
59@@ -0,0 +1,55 @@
60+/* GLIB - Library of useful routines for C programming
61+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
62+ *
63+ * This library is free software; you can redistribute it and/or
64+ * modify it under the terms of the GNU Lesser General Public
65+ * License as published by the Free Software Foundation; either
66+ * version 2.1 of the License, or (at your option) any later version.
67+ *
68+ * This library is distributed in the hope that it will be useful,
69+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
70+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
71+ * Lesser General Public License for more details.
72+ *
73+ * You should have received a copy of the GNU Lesser General Public
74+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
75+ */
76+
77+#include <glib.h>
78+#include <string.h>
79+
80+/*
81+ * g_memdup2:
82+ * @mem: (nullable): the memory to copy.
83+ * @byte_size: the number of bytes to copy.
84+ *
85+ * Allocates @byte_size bytes of memory, and copies @byte_size bytes into it
86+ * from @mem. If @mem is %NULL it returns %NULL.
87+ *
88+ * This replaces g_memdup(), which was prone to integer overflows when
89+ * converting the argument from a #gsize to a #guint.
90+ *
91+ * This static inline version is a backport of the new public API from
92+ * GLib 2.68, kept internal to GLib for backport to older stable releases.
93+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2319.
94+ *
95+ * Returns: (nullable): a pointer to the newly-allocated copy of the memory,
96+ * or %NULL if @mem is %NULL.
97+ * Since: 2.68
98+ */
99+static inline gpointer
100+g_memdup2 (gconstpointer mem,
101+ gsize byte_size)
102+{
103+ gpointer new_mem;
104+
105+ if (mem && byte_size != 0)
106+ {
107+ new_mem = g_malloc (byte_size);
108+ memcpy (new_mem, mem, byte_size);
109+ }
110+ else
111+ new_mem = NULL;
112+
113+ return new_mem;
114+}
115--- a/glib/meson.build
116+++ b/glib/meson.build
117@@ -268,6 +268,7 @@ glib_sources = files(
118 'gslist.c',
119 'gstdio.c',
120 'gstrfuncs.c',
121+ 'gstrfuncsprivate.h',
122 'gstring.c',
123 'gstringchunk.c',
124 'gtestutils.c',
125--- a/glib/tests/strfuncs.c
126+++ b/glib/tests/strfuncs.c
127@@ -32,6 +32,8 @@
128 #include <string.h>
129 #include "glib.h"
130
131+#include "gstrfuncsprivate.h"
132+
133 #if defined (_MSC_VER) && (_MSC_VER <= 1800)
134 #define isnan(x) _isnan(x)
135
136@@ -219,6 +221,26 @@ test_memdup (void)
137 g_free (str_dup);
138 }
139
140+/* Testing g_memdup2() function with various positive and negative cases */
141+static void
142+test_memdup2 (void)
143+{
144+ gchar *str_dup = NULL;
145+ const gchar *str = "The quick brown fox jumps over the lazy dog";
146+
147+ /* Testing negative cases */
148+ g_assert_null (g_memdup2 (NULL, 1024));
149+ g_assert_null (g_memdup2 (str, 0));
150+ g_assert_null (g_memdup2 (NULL, 0));
151+
152+ /* Testing normal usage cases */
153+ str_dup = g_memdup2 (str, strlen (str) + 1);
154+ g_assert_nonnull (str_dup);
155+ g_assert_cmpstr (str, ==, str_dup);
156+
157+ g_free (str_dup);
158+}
159+
160 /* Testing g_strpcpy() function with various positive and negative cases */
161 static void
162 test_stpcpy (void)
163@@ -2523,6 +2545,7 @@ main (int argc,
164 g_test_add_func ("/strfuncs/has-prefix", test_has_prefix);
165 g_test_add_func ("/strfuncs/has-suffix", test_has_suffix);
166 g_test_add_func ("/strfuncs/memdup", test_memdup);
167+ g_test_add_func ("/strfuncs/memdup2", test_memdup2);
168 g_test_add_func ("/strfuncs/stpcpy", test_stpcpy);
169 g_test_add_func ("/strfuncs/str_match_string", test_str_match_string);
170 g_test_add_func ("/strfuncs/str_tokenize_and_fold", test_str_tokenize_and_fold);
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-02.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-02.patch
new file mode 100644
index 0000000000..20137ea5f3
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-02.patch
@@ -0,0 +1,249 @@
1From be8834340a2d928ece82025463ae23dee2c333d0 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Thu, 4 Feb 2021 13:37:56 +0000
4Subject: [PATCH 02/11] gio: Use g_memdup2() instead of g_memdup() in obvious
5 places
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10Convert all the call sites which use `g_memdup()`’s length argument
11trivially (for example, by passing a `sizeof()`), so that they use
12`g_memdup2()` instead.
13
14In almost all of these cases the use of `g_memdup()` would not have
15caused problems, but it will soon be deprecated, so best port away from
16it.
17
18Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
19Helps: #2319
20
21Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
22CVE: CVE-2021-27219
23Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
24Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
25
26---
27 gio/gdbusconnection.c | 5 +++--
28 gio/gdbusinterfaceskeleton.c | 3 ++-
29 gio/gfile.c | 7 ++++---
30 gio/gsettingsschema.c | 5 +++--
31 gio/gwin32registrykey.c | 8 +++++---
32 gio/tests/async-close-output-stream.c | 6 ++++--
33 gio/tests/gdbus-export.c | 5 +++--
34 gio/win32/gwinhttpfile.c | 9 +++++----
35 8 files changed, 29 insertions(+), 19 deletions(-)
36
37--- a/gio/gdbusconnection.c
38+++ b/gio/gdbusconnection.c
39@@ -110,6 +110,7 @@
40 #include "gasyncinitable.h"
41 #include "giostream.h"
42 #include "gasyncresult.h"
43+#include "gstrfuncsprivate.h"
44 #include "gtask.h"
45 #include "gmarshal-internal.h"
46
47@@ -4007,7 +4008,7 @@ _g_dbus_interface_vtable_copy (const GDB
48 /* Don't waste memory by copying padding - remember to update this
49 * when changing struct _GDBusInterfaceVTable in gdbusconnection.h
50 */
51- return g_memdup ((gconstpointer) vtable, 3 * sizeof (gpointer));
52+ return g_memdup2 ((gconstpointer) vtable, 3 * sizeof (gpointer));
53 }
54
55 static void
56@@ -4024,7 +4025,7 @@ _g_dbus_subtree_vtable_copy (const GDBus
57 /* Don't waste memory by copying padding - remember to update this
58 * when changing struct _GDBusSubtreeVTable in gdbusconnection.h
59 */
60- return g_memdup ((gconstpointer) vtable, 3 * sizeof (gpointer));
61+ return g_memdup2 ((gconstpointer) vtable, 3 * sizeof (gpointer));
62 }
63
64 static void
65--- a/gio/gdbusinterfaceskeleton.c
66+++ b/gio/gdbusinterfaceskeleton.c
67@@ -28,6 +28,7 @@
68 #include "gdbusmethodinvocation.h"
69 #include "gdbusconnection.h"
70 #include "gmarshal-internal.h"
71+#include "gstrfuncsprivate.h"
72 #include "gtask.h"
73 #include "gioerror.h"
74
75@@ -701,7 +702,7 @@ add_connection_locked (GDBusInterfaceSke
76 * properly before building the hooked_vtable, so we create it
77 * once at the last minute.
78 */
79- interface_->priv->hooked_vtable = g_memdup (g_dbus_interface_skeleton_get_vtable (interface_), sizeof (GDBusInterfaceVTable));
80+ interface_->priv->hooked_vtable = g_memdup2 (g_dbus_interface_skeleton_get_vtable (interface_), sizeof (GDBusInterfaceVTable));
81 interface_->priv->hooked_vtable->method_call = skeleton_intercept_handle_method_call;
82 }
83
84--- a/gio/gfile.c
85+++ b/gio/gfile.c
86@@ -60,6 +60,7 @@
87 #include "gasyncresult.h"
88 #include "gioerror.h"
89 #include "glibintl.h"
90+#include "gstrfuncsprivate.h"
91
92
93 /**
94@@ -7854,7 +7855,7 @@ measure_disk_usage_progress (gboolean re
95 g_main_context_invoke_full (g_task_get_context (task),
96 g_task_get_priority (task),
97 measure_disk_usage_invoke_progress,
98- g_memdup (&progress, sizeof progress),
99+ g_memdup2 (&progress, sizeof progress),
100 g_free);
101 }
102
103@@ -7872,7 +7873,7 @@ measure_disk_usage_thread (GTask
104 data->progress_callback ? measure_disk_usage_progress : NULL, task,
105 &result.disk_usage, &result.num_dirs, &result.num_files,
106 &error))
107- g_task_return_pointer (task, g_memdup (&result, sizeof result), g_free);
108+ g_task_return_pointer (task, g_memdup2 (&result, sizeof result), g_free);
109 else
110 g_task_return_error (task, error);
111 }
112@@ -7896,7 +7897,7 @@ g_file_real_measure_disk_usage_async (GF
113
114 task = g_task_new (file, cancellable, callback, user_data);
115 g_task_set_source_tag (task, g_file_real_measure_disk_usage_async);
116- g_task_set_task_data (task, g_memdup (&data, sizeof data), g_free);
117+ g_task_set_task_data (task, g_memdup2 (&data, sizeof data), g_free);
118 g_task_set_priority (task, io_priority);
119
120 g_task_run_in_thread (task, measure_disk_usage_thread);
121--- a/gio/gsettingsschema.c
122+++ b/gio/gsettingsschema.c
123@@ -20,6 +20,7 @@
124
125 #include "gsettingsschema-internal.h"
126 #include "gsettings.h"
127+#include "gstrfuncsprivate.h"
128
129 #include "gvdb/gvdb-reader.h"
130 #include "strinfo.c"
131@@ -1067,9 +1068,9 @@ g_settings_schema_list_children (GSettin
132
133 if (g_str_has_suffix (key, "/"))
134 {
135- gint length = strlen (key);
136+ gsize length = strlen (key);
137
138- strv[j] = g_memdup (key, length);
139+ strv[j] = g_memdup2 (key, length);
140 strv[j][length - 1] = '\0';
141 j++;
142 }
143--- a/gio/gwin32registrykey.c
144+++ b/gio/gwin32registrykey.c
145@@ -28,6 +28,8 @@
146 #include <ntstatus.h>
147 #include <winternl.h>
148
149+#include "gstrfuncsprivate.h"
150+
151 #ifndef _WDMDDK_
152 typedef enum _KEY_INFORMATION_CLASS {
153 KeyBasicInformation,
154@@ -247,7 +249,7 @@ g_win32_registry_value_iter_copy (const
155 new_iter->value_name_size = iter->value_name_size;
156
157 if (iter->value_data != NULL)
158- new_iter->value_data = g_memdup (iter->value_data, iter->value_data_size);
159+ new_iter->value_data = g_memdup2 (iter->value_data, iter->value_data_size);
160
161 new_iter->value_data_size = iter->value_data_size;
162
163@@ -268,8 +270,8 @@ g_win32_registry_value_iter_copy (const
164 new_iter->value_data_expanded_charsize = iter->value_data_expanded_charsize;
165
166 if (iter->value_data_expanded_u8 != NULL)
167- new_iter->value_data_expanded_u8 = g_memdup (iter->value_data_expanded_u8,
168- iter->value_data_expanded_charsize);
169+ new_iter->value_data_expanded_u8 = g_memdup2 (iter->value_data_expanded_u8,
170+ iter->value_data_expanded_charsize);
171
172 new_iter->value_data_expanded_u8_size = iter->value_data_expanded_charsize;
173
174--- a/gio/tests/async-close-output-stream.c
175+++ b/gio/tests/async-close-output-stream.c
176@@ -24,6 +24,8 @@
177 #include <stdlib.h>
178 #include <string.h>
179
180+#include "gstrfuncsprivate.h"
181+
182 #define DATA_TO_WRITE "Hello world\n"
183
184 typedef struct
185@@ -147,9 +149,9 @@ prepare_data (SetupData *data,
186
187 data->expected_size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->data_stream));
188
189- g_assert_cmpint (data->expected_size, >, 0);
190+ g_assert_cmpuint (data->expected_size, >, 0);
191
192- data->expected_output = g_memdup (written, (guint)data->expected_size);
193+ data->expected_output = g_memdup2 (written, data->expected_size);
194
195 /* then recreate the streams and prepare them for the asynchronous close */
196 destroy_streams (data);
197--- a/gio/tests/gdbus-export.c
198+++ b/gio/tests/gdbus-export.c
199@@ -23,6 +23,7 @@
200 #include <string.h>
201
202 #include "gdbus-tests.h"
203+#include "gstrfuncsprivate.h"
204
205 /* all tests rely on a shared mainloop */
206 static GMainLoop *loop = NULL;
207@@ -671,7 +672,7 @@ subtree_introspect (GDBusConnection
208 g_assert_not_reached ();
209 }
210
211- return g_memdup (interfaces, 2 * sizeof (void *));
212+ return g_memdup2 (interfaces, 2 * sizeof (void *));
213 }
214
215 static const GDBusInterfaceVTable *
216@@ -727,7 +728,7 @@ dynamic_subtree_introspect (GDBusConnect
217 {
218 const GDBusInterfaceInfo *interfaces[2] = { &dyna_interface_info, NULL };
219
220- return g_memdup (interfaces, 2 * sizeof (void *));
221+ return g_memdup2 (interfaces, 2 * sizeof (void *));
222 }
223
224 static const GDBusInterfaceVTable *
225--- a/gio/win32/gwinhttpfile.c
226+++ b/gio/win32/gwinhttpfile.c
227@@ -29,6 +29,7 @@
228 #include "gio/gfile.h"
229 #include "gio/gfileattribute.h"
230 #include "gio/gfileinfo.h"
231+#include "gstrfuncsprivate.h"
232 #include "gwinhttpfile.h"
233 #include "gwinhttpfileinputstream.h"
234 #include "gwinhttpfileoutputstream.h"
235@@ -393,10 +394,10 @@
236 child = g_object_new (G_TYPE_WINHTTP_FILE, NULL);
237 child->vfs = winhttp_file->vfs;
238 child->url = winhttp_file->url;
239- child->url.lpszScheme = g_memdup (winhttp_file->url.lpszScheme, (winhttp_file->url.dwSchemeLength+1)*2);
240- child->url.lpszHostName = g_memdup (winhttp_file->url.lpszHostName, (winhttp_file->url.dwHostNameLength+1)*2);
241- child->url.lpszUserName = g_memdup (winhttp_file->url.lpszUserName, (winhttp_file->url.dwUserNameLength+1)*2);
242- child->url.lpszPassword = g_memdup (winhttp_file->url.lpszPassword, (winhttp_file->url.dwPasswordLength+1)*2);
243+ child->url.lpszScheme = g_memdup2 (winhttp_file->url.lpszScheme, (winhttp_file->url.dwSchemeLength+1)*2);
244+ child->url.lpszHostName = g_memdup2 (winhttp_file->url.lpszHostName, (winhttp_file->url.dwHostNameLength+1)*2);
245+ child->url.lpszUserName = g_memdup2 (winhttp_file->url.lpszUserName, (winhttp_file->url.dwUserNameLength+1)*2);
246+ child->url.lpszPassword = g_memdup2 (winhttp_file->url.lpszPassword, (winhttp_file->url.dwPasswordLength+1)*2);
247 child->url.lpszUrlPath = wnew_path;
248 child->url.dwUrlPathLength = wcslen (wnew_path);
249 child->url.lpszExtraInfo = NULL;
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-03.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-03.patch
new file mode 100644
index 0000000000..eceff161a6
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-03.patch
@@ -0,0 +1,131 @@
1From 6110caea45b235420b98cd41d845cc92238f6781 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Thu, 4 Feb 2021 13:39:25 +0000
4Subject: [PATCH 03/11] gobject: Use g_memdup2() instead of g_memdup() in
5 obvious places
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10Convert all the call sites which use `g_memdup()`’s length argument
11trivially (for example, by passing a `sizeof()`), so that they use
12`g_memdup2()` instead.
13
14In almost all of these cases the use of `g_memdup()` would not have
15caused problems, but it will soon be deprecated, so best port away from
16it.
17
18Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
19Helps: #2319
20
21Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
22CVE: CVE-2021-27219
23Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
24Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
25
26---
27 gobject/gsignal.c | 3 ++-
28 gobject/gtype.c | 9 +++++----
29 gobject/gtypemodule.c | 3 ++-
30 gobject/tests/param.c | 4 +++-
31 4 files changed, 12 insertions(+), 7 deletions(-)
32
33--- a/gobject/gsignal.c
34+++ b/gobject/gsignal.c
35@@ -28,6 +28,7 @@
36 #include <signal.h>
37
38 #include "gsignal.h"
39+#include "gstrfuncsprivate.h"
40 #include "gtype-private.h"
41 #include "gbsearcharray.h"
42 #include "gvaluecollector.h"
43@@ -1809,7 +1810,7 @@ g_signal_newv (const gchar *signal
44 node->single_va_closure_is_valid = FALSE;
45 node->flags = signal_flags & G_SIGNAL_FLAGS_MASK;
46 node->n_params = n_params;
47- node->param_types = g_memdup (param_types, sizeof (GType) * n_params);
48+ node->param_types = g_memdup2 (param_types, sizeof (GType) * n_params);
49 node->return_type = return_type;
50 node->class_closure_bsa = NULL;
51 if (accumulator)
52--- a/gobject/gtype.c
53+++ b/gobject/gtype.c
54@@ -33,6 +33,7 @@
55
56 #include "glib-private.h"
57 #include "gconstructor.h"
58+#include "gstrfuncsprivate.h"
59
60 #ifdef G_OS_WIN32
61 #include <windows.h>
62@@ -1470,7 +1471,7 @@ type_add_interface_Wm (TypeNode
63 iholder->next = iface_node_get_holders_L (iface);
64 iface_node_set_holders_W (iface, iholder);
65 iholder->instance_type = NODE_TYPE (node);
66- iholder->info = info ? g_memdup (info, sizeof (*info)) : NULL;
67+ iholder->info = info ? g_memdup2 (info, sizeof (*info)) : NULL;
68 iholder->plugin = plugin;
69
70 /* create an iface entry for this type */
71@@ -1731,7 +1732,7 @@ type_iface_retrieve_holder_info_Wm (Type
72 INVALID_RECURSION ("g_type_plugin_*", iholder->plugin, NODE_NAME (iface));
73
74 check_interface_info_I (iface, instance_type, &tmp_info);
75- iholder->info = g_memdup (&tmp_info, sizeof (tmp_info));
76+ iholder->info = g_memdup2 (&tmp_info, sizeof (tmp_info));
77 }
78
79 return iholder; /* we don't modify write lock upon returning NULL */
80@@ -2016,10 +2017,10 @@ type_iface_vtable_base_init_Wm (TypeNode
81 IFaceEntry *pentry = type_lookup_iface_entry_L (pnode, iface);
82
83 if (pentry)
84- vtable = g_memdup (pentry->vtable, iface->data->iface.vtable_size);
85+ vtable = g_memdup2 (pentry->vtable, iface->data->iface.vtable_size);
86 }
87 if (!vtable)
88- vtable = g_memdup (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size);
89+ vtable = g_memdup2 (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size);
90 entry->vtable = vtable;
91 vtable->g_type = NODE_TYPE (iface);
92 vtable->g_instance_type = NODE_TYPE (node);
93--- a/gobject/gtypemodule.c
94+++ b/gobject/gtypemodule.c
95@@ -19,6 +19,7 @@
96
97 #include <stdlib.h>
98
99+#include "gstrfuncsprivate.h"
100 #include "gtypeplugin.h"
101 #include "gtypemodule.h"
102
103@@ -436,7 +437,7 @@ g_type_module_register_type (GTypeModule
104 module_type_info->loaded = TRUE;
105 module_type_info->info = *type_info;
106 if (type_info->value_table)
107- module_type_info->info.value_table = g_memdup (type_info->value_table,
108+ module_type_info->info.value_table = g_memdup2 (type_info->value_table,
109 sizeof (GTypeValueTable));
110
111 return module_type_info->type;
112--- a/gobject/tests/param.c
113+++ b/gobject/tests/param.c
114@@ -2,6 +2,8 @@
115 #include <glib-object.h>
116 #include <stdlib.h>
117
118+#include "gstrfuncsprivate.h"
119+
120 static void
121 test_param_value (void)
122 {
123@@ -874,7 +876,7 @@ main (int argc, char *argv[])
124 test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d",
125 data.change_this_flag, data.change_this_type,
126 data.use_this_flag, data.use_this_type);
127- test_data = g_memdup (&data, sizeof (TestParamImplementData));
128+ test_data = g_memdup2 (&data, sizeof (TestParamImplementData));
129 g_test_add_data_func_full (test_path, test_data, test_param_implement_child, g_free);
130 g_free (test_path);
131 }
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-04.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-04.patch
new file mode 100644
index 0000000000..6a3ac6b552
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-04.patch
@@ -0,0 +1,298 @@
1Backport of:
2
3From 0736b7c1e7cf4232c5d7eb2b0fbfe9be81bd3baa Mon Sep 17 00:00:00 2001
4From: Philip Withnall <pwithnall@endlessos.org>
5Date: Thu, 4 Feb 2021 13:41:21 +0000
6Subject: [PATCH 04/11] glib: Use g_memdup2() instead of g_memdup() in obvious
7 places
8MIME-Version: 1.0
9Content-Type: text/plain; charset=UTF-8
10Content-Transfer-Encoding: 8bit
11
12Convert all the call sites which use `g_memdup()`’s length argument
13trivially (for example, by passing a `sizeof()` or an existing `gsize`
14variable), so that they use `g_memdup2()` instead.
15
16In almost all of these cases the use of `g_memdup()` would not have
17caused problems, but it will soon be deprecated, so best port away from
18it
19
20In particular, this fixes an overflow within `g_bytes_new()`, identified
21as GHSL-2021-045 by GHSL team member Kevin Backhouse.
22
23Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
24Fixes: GHSL-2021-045
25Helps: #2319
26
27Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
28CVE: CVE-2021-27219
29Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
30Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
31
32---
33 glib/gbytes.c | 6 ++++--
34 glib/gdir.c | 3 ++-
35 glib/ghash.c | 7 ++++---
36 glib/giochannel.c | 5 +++--
37 glib/gslice.c | 3 ++-
38 glib/gtestutils.c | 3 ++-
39 glib/gvariant.c | 7 ++++---
40 glib/gvarianttype.c | 3 ++-
41 glib/tests/array-test.c | 4 +++-
42 glib/tests/option-context.c | 6 ++++--
43 glib/tests/uri.c | 8 +++++---
44 11 files changed, 35 insertions(+), 20 deletions(-)
45
46--- a/glib/gbytes.c
47+++ b/glib/gbytes.c
48@@ -34,6 +34,8 @@
49
50 #include <string.h>
51
52+#include "gstrfuncsprivate.h"
53+
54 /**
55 * GBytes:
56 *
57@@ -95,7 +97,7 @@ g_bytes_new (gconstpointer data,
58 {
59 g_return_val_if_fail (data != NULL || size == 0, NULL);
60
61- return g_bytes_new_take (g_memdup (data, size), size);
62+ return g_bytes_new_take (g_memdup2 (data, size), size);
63 }
64
65 /**
66@@ -499,7 +501,7 @@ g_bytes_unref_to_data (GBytes *bytes,
67 * Copy: Non g_malloc (or compatible) allocator, or static memory,
68 * so we have to copy, and then unref.
69 */
70- result = g_memdup (bytes->data, bytes->size);
71+ result = g_memdup2 (bytes->data, bytes->size);
72 *size = bytes->size;
73 g_bytes_unref (bytes);
74 }
75--- a/glib/gdir.c
76+++ b/glib/gdir.c
77@@ -37,6 +37,7 @@
78 #include "gconvert.h"
79 #include "gfileutils.h"
80 #include "gstrfuncs.h"
81+#include "gstrfuncsprivate.h"
82 #include "gtestutils.h"
83 #include "glibintl.h"
84
85@@ -112,7 +113,7 @@ g_dir_open_with_errno (const gchar *path
86 return NULL;
87 #endif
88
89- return g_memdup (&dir, sizeof dir);
90+ return g_memdup2 (&dir, sizeof dir);
91 }
92
93 /**
94--- a/glib/ghash.c
95+++ b/glib/ghash.c
96@@ -34,6 +34,7 @@
97 #include "gmacros.h"
98 #include "glib-private.h"
99 #include "gstrfuncs.h"
100+#include "gstrfuncsprivate.h"
101 #include "gatomic.h"
102 #include "gtestutils.h"
103 #include "gslice.h"
104@@ -962,7 +963,7 @@ g_hash_table_ensure_keyval_fits (GHashTa
105 if (hash_table->have_big_keys)
106 {
107 if (key != value)
108- hash_table->values = g_memdup (hash_table->keys, sizeof (gpointer) * hash_table->size);
109+ hash_table->values = g_memdup2 (hash_table->keys, sizeof (gpointer) * hash_table->size);
110 /* Keys and values are both big now, so no need for further checks */
111 return;
112 }
113@@ -970,7 +971,7 @@ g_hash_table_ensure_keyval_fits (GHashTa
114 {
115 if (key != value)
116 {
117- hash_table->values = g_memdup (hash_table->keys, sizeof (guint) * hash_table->size);
118+ hash_table->values = g_memdup2 (hash_table->keys, sizeof (guint) * hash_table->size);
119 is_a_set = FALSE;
120 }
121 }
122@@ -998,7 +999,7 @@ g_hash_table_ensure_keyval_fits (GHashTa
123
124 /* Just split if necessary */
125 if (is_a_set && key != value)
126- hash_table->values = g_memdup (hash_table->keys, sizeof (gpointer) * hash_table->size);
127+ hash_table->values = g_memdup2 (hash_table->keys, sizeof (gpointer) * hash_table->size);
128
129 #endif
130 }
131--- a/glib/giochannel.c
132+++ b/glib/giochannel.c
133@@ -35,7 +35,7 @@
134 #include <errno.h>
135
136 #include "giochannel.h"
137-
138+#include "gstrfuncsprivate.h"
139 #include "gstrfuncs.h"
140 #include "gtestutils.h"
141 #include "glibintl.h"
142
143@@ -1673,10 +1674,10 @@ g_io_channel_read_line (GIOChannel *cha
144
145 /* Copy the read bytes (including any embedded nuls) and nul-terminate.
146 * `USE_BUF (channel)->str` is guaranteed to be nul-terminated as it’s a
147- * #GString, so it’s safe to call g_memdup() with +1 length to allocate
148+ * #GString, so it’s safe to call g_memdup2() with +1 length to allocate
149 * a nul-terminator. */
150 g_assert (USE_BUF (channel));
151- line = g_memdup (USE_BUF (channel)->str, got_length + 1);
152+ line = g_memdup2 (USE_BUF (channel)->str, got_length + 1);
153 line[got_length] = '\0';
154 *str_return = g_steal_pointer (&line);
155 g_string_erase (USE_BUF (channel), 0, got_length);
156--- a/glib/gslice.c
157+++ b/glib/gslice.c
158@@ -41,6 +41,7 @@
159 #include "gmain.h"
160 #include "gmem.h" /* gslice.h */
161 #include "gstrfuncs.h"
162+#include "gstrfuncsprivate.h"
163 #include "gutils.h"
164 #include "gtrashstack.h"
165 #include "gtestutils.h"
166@@ -350,7 +351,7 @@ g_slice_get_config_state (GSliceConfig c
167 array[i++] = allocator->contention_counters[address];
168 array[i++] = allocator_get_magazine_threshold (allocator, address);
169 *n_values = i;
170- return g_memdup (array, sizeof (array[0]) * *n_values);
171+ return g_memdup2 (array, sizeof (array[0]) * *n_values);
172 default:
173 return NULL;
174 }
175--- a/glib/gtestutils.c
176+++ b/glib/gtestutils.c
177@@ -49,6 +49,7 @@
178 #include "gpattern.h"
179 #include "grand.h"
180 #include "gstrfuncs.h"
181+#include "gstrfuncsprivate.h"
182 #include "gtimer.h"
183 #include "gslice.h"
184 #include "gspawn.h"
185@@ -3803,7 +3804,7 @@ g_test_log_extract (GTestLogBuffer *tbuf
186 if (p <= tbuffer->data->str + mlength)
187 {
188 g_string_erase (tbuffer->data, 0, mlength);
189- tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup (&msg, sizeof (msg)));
190+ tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup2 (&msg, sizeof (msg)));
191 return TRUE;
192 }
193
194--- a/glib/gvariant.c
195+++ b/glib/gvariant.c
196@@ -33,6 +33,7 @@
197
198 #include <string.h>
199
200+#include "gstrfuncsprivate.h"
201
202 /**
203 * SECTION:gvariant
204@@ -725,7 +726,7 @@ g_variant_new_variant (GVariant *value)
205 g_variant_ref_sink (value);
206
207 return g_variant_new_from_children (G_VARIANT_TYPE_VARIANT,
208- g_memdup (&value, sizeof value),
209+ g_memdup2 (&value, sizeof value),
210 1, g_variant_is_trusted (value));
211 }
212
213@@ -1229,7 +1230,7 @@ g_variant_new_fixed_array (const GVarian
214 return NULL;
215 }
216
217- data = g_memdup (elements, n_elements * element_size);
218+ data = g_memdup2 (elements, n_elements * element_size);
219 value = g_variant_new_from_data (array_type, data,
220 n_elements * element_size,
221 FALSE, g_free, data);
222@@ -1908,7 +1909,7 @@ g_variant_dup_bytestring (GVariant *valu
223 if (length)
224 *length = size;
225
226- return g_memdup (original, size + 1);
227+ return g_memdup2 (original, size + 1);
228 }
229
230 /**
231--- a/glib/gvarianttype.c
232+++ b/glib/gvarianttype.c
233@@ -28,6 +28,7 @@
234
235 #include <string.h>
236
237+#include "gstrfuncsprivate.h"
238
239 /**
240 * SECTION:gvarianttype
241@@ -1181,7 +1182,7 @@ g_variant_type_new_tuple (const GVariant
242 g_assert (offset < sizeof buffer);
243 buffer[offset++] = ')';
244
245- return (GVariantType *) g_memdup (buffer, offset);
246+ return (GVariantType *) g_memdup2 (buffer, offset);
247 }
248
249 /**
250--- a/glib/tests/array-test.c
251+++ b/glib/tests/array-test.c
252@@ -29,6 +29,8 @@
253 #include <string.h>
254 #include "glib.h"
255
256+#include "gstrfuncsprivate.h"
257+
258 /* Test data to be passed to any function which calls g_array_new(), providing
259 * the parameters for that call. Most #GArray tests should be repeated for all
260 * possible values of #ArrayTestData. */
261@@ -1917,7 +1919,7 @@ byte_array_new_take (void)
262 GByteArray *gbarray;
263 guint8 *data;
264
265- data = g_memdup ("woooweeewow", 11);
266+ data = g_memdup2 ("woooweeewow", 11);
267 gbarray = g_byte_array_new_take (data, 11);
268 g_assert (gbarray->data == data);
269 g_assert_cmpuint (gbarray->len, ==, 11);
270--- a/glib/tests/option-context.c
271+++ b/glib/tests/option-context.c
272@@ -27,6 +27,8 @@
273 #include <string.h>
274 #include <locale.h>
275
276+#include "gstrfuncsprivate.h"
277+
278 static GOptionEntry main_entries[] = {
279 { "main-switch", 0, 0,
280 G_OPTION_ARG_NONE, NULL,
281@@ -256,7 +258,7 @@ join_stringv (int argc, char **argv)
282 static char **
283 copy_stringv (char **argv, int argc)
284 {
285- return g_memdup (argv, sizeof (char *) * (argc + 1));
286+ return g_memdup2 (argv, sizeof (char *) * (argc + 1));
287 }
288
289 static void
290@@ -2323,7 +2325,7 @@ test_group_parse (void)
291 g_option_context_add_group (context, group);
292
293 argv = split_string ("program --test arg1 -f arg2 --group-test arg3 --frob arg4 -z arg5", &argc);
294- orig_argv = g_memdup (argv, (argc + 1) * sizeof (char *));
295+ orig_argv = g_memdup2 (argv, (argc + 1) * sizeof (char *));
296
297 retval = g_option_context_parse (context, &argc, &argv, &error);
298
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-05.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-05.patch
new file mode 100644
index 0000000000..4f86522d00
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-05.patch
@@ -0,0 +1,54 @@
1From 0cbad673215ec8a049b7fe2ff44b0beed31b376e Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Thu, 4 Feb 2021 16:12:24 +0000
4Subject: [PATCH 05/11] gwinhttpfile: Avoid arithmetic overflow when
5 calculating a size
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10The members of `URL_COMPONENTS` (`winhttp_file->url`) are `DWORD`s, i.e.
1132-bit unsigned integers. Adding to and multiplying them may cause them
12to overflow the unsigned integer bounds, even if the result is passed to
13`g_memdup2()` which accepts a `gsize`.
14
15Cast the `URL_COMPONENTS` members to `gsize` first to ensure that the
16arithmetic is done in terms of `gsize`s rather than unsigned integers.
17
18Spotted by Sebastian Dröge.
19
20Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
21Helps: #2319
22
23Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
24CVE: CVE-2021-27219
25Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
26Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
27
28---
29 gio/win32/gwinhttpfile.c | 8 ++++----
30 1 file changed, 4 insertions(+), 4 deletions(-)
31
32diff --git a/gio/win32/gwinhttpfile.c b/gio/win32/gwinhttpfile.c
33index 3f8fbd838..e0340e247 100644
34--- a/gio/win32/gwinhttpfile.c
35+++ b/gio/win32/gwinhttpfile.c
36@@ -410,10 +410,10 @@ g_winhttp_file_resolve_relative_path (GFile *file,
37 child = g_object_new (G_TYPE_WINHTTP_FILE, NULL);
38 child->vfs = winhttp_file->vfs;
39 child->url = winhttp_file->url;
40- child->url.lpszScheme = g_memdup2 (winhttp_file->url.lpszScheme, (winhttp_file->url.dwSchemeLength+1)*2);
41- child->url.lpszHostName = g_memdup2 (winhttp_file->url.lpszHostName, (winhttp_file->url.dwHostNameLength+1)*2);
42- child->url.lpszUserName = g_memdup2 (winhttp_file->url.lpszUserName, (winhttp_file->url.dwUserNameLength+1)*2);
43- child->url.lpszPassword = g_memdup2 (winhttp_file->url.lpszPassword, (winhttp_file->url.dwPasswordLength+1)*2);
44+ child->url.lpszScheme = g_memdup2 (winhttp_file->url.lpszScheme, ((gsize) winhttp_file->url.dwSchemeLength + 1) * 2);
45+ child->url.lpszHostName = g_memdup2 (winhttp_file->url.lpszHostName, ((gsize) winhttp_file->url.dwHostNameLength + 1) * 2);
46+ child->url.lpszUserName = g_memdup2 (winhttp_file->url.lpszUserName, ((gsize) winhttp_file->url.dwUserNameLength + 1) * 2);
47+ child->url.lpszPassword = g_memdup2 (winhttp_file->url.lpszPassword, ((gsize) winhttp_file->url.dwPasswordLength + 1) * 2);
48 child->url.lpszUrlPath = wnew_path;
49 child->url.dwUrlPathLength = wcslen (wnew_path);
50 child->url.lpszExtraInfo = NULL;
51--
52GitLab
53
54
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-06.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-06.patch
new file mode 100644
index 0000000000..d8043f5e29
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-06.patch
@@ -0,0 +1,101 @@
1From f9ee2275cbc312c0b4cdbc338a4fbb76eb36fb9a Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Thu, 4 Feb 2021 13:49:00 +0000
4Subject: [PATCH 06/11] gdatainputstream: Handle stop_chars_len internally as
5 gsize
6
7Previously it was handled as a `gssize`, which meant that if the
8`stop_chars` string was longer than `G_MAXSSIZE` there would be an
9overflow.
10
11Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
12Helps: #2319
13
14Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
15CVE: CVE-2021-27219
16Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
17Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
18
19---
20 gio/gdatainputstream.c | 25 +++++++++++++++++--------
21 1 file changed, 17 insertions(+), 8 deletions(-)
22
23diff --git a/gio/gdatainputstream.c b/gio/gdatainputstream.c
24index 2e7750cb5..2cdcbda19 100644
25--- a/gio/gdatainputstream.c
26+++ b/gio/gdatainputstream.c
27@@ -27,6 +27,7 @@
28 #include "gioenumtypes.h"
29 #include "gioerror.h"
30 #include "glibintl.h"
31+#include "gstrfuncsprivate.h"
32
33 #include <string.h>
34
35@@ -856,7 +857,7 @@ static gssize
36 scan_for_chars (GDataInputStream *stream,
37 gsize *checked_out,
38 const char *stop_chars,
39- gssize stop_chars_len)
40+ gsize stop_chars_len)
41 {
42 GBufferedInputStream *bstream;
43 const char *buffer;
44@@ -952,7 +953,7 @@ typedef struct
45 gsize checked;
46
47 gchar *stop_chars;
48- gssize stop_chars_len;
49+ gsize stop_chars_len;
50 gsize length;
51 } GDataInputStreamReadData;
52
53@@ -1078,12 +1079,17 @@ g_data_input_stream_read_async (GDataInputStream *stream,
54 {
55 GDataInputStreamReadData *data;
56 GTask *task;
57+ gsize stop_chars_len_unsigned;
58
59 data = g_slice_new0 (GDataInputStreamReadData);
60- if (stop_chars_len == -1)
61- stop_chars_len = strlen (stop_chars);
62- data->stop_chars = g_memdup (stop_chars, stop_chars_len);
63- data->stop_chars_len = stop_chars_len;
64+
65+ if (stop_chars_len < 0)
66+ stop_chars_len_unsigned = strlen (stop_chars);
67+ else
68+ stop_chars_len_unsigned = (gsize) stop_chars_len;
69+
70+ data->stop_chars = g_memdup2 (stop_chars, stop_chars_len_unsigned);
71+ data->stop_chars_len = stop_chars_len_unsigned;
72 data->last_saw_cr = FALSE;
73
74 task = g_task_new (stream, cancellable, callback, user_data);
75@@ -1338,17 +1344,20 @@ g_data_input_stream_read_upto (GDataInputStream *stream,
76 gssize found_pos;
77 gssize res;
78 char *data_until;
79+ gsize stop_chars_len_unsigned;
80
81 g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);
82
83 if (stop_chars_len < 0)
84- stop_chars_len = strlen (stop_chars);
85+ stop_chars_len_unsigned = strlen (stop_chars);
86+ else
87+ stop_chars_len_unsigned = (gsize) stop_chars_len;
88
89 bstream = G_BUFFERED_INPUT_STREAM (stream);
90
91 checked = 0;
92
93- while ((found_pos = scan_for_chars (stream, &checked, stop_chars, stop_chars_len)) == -1)
94+ while ((found_pos = scan_for_chars (stream, &checked, stop_chars, stop_chars_len_unsigned)) == -1)
95 {
96 if (g_buffered_input_stream_get_available (bstream) ==
97 g_buffered_input_stream_get_buffer_size (bstream))
98--
99GitLab
100
101
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-07.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-07.patch
new file mode 100644
index 0000000000..f183939c45
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-07.patch
@@ -0,0 +1,76 @@
1From 2aaf593a9eb96d84fe3be740aca2810a97d95592 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Thu, 4 Feb 2021 13:50:37 +0000
4Subject: [PATCH 07/11] gwin32: Use gsize internally in g_wcsdup()
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9This allows it to handle strings up to length `G_MAXSIZE` — previously
10it would overflow with such strings.
11
12Update the several copies of it identically.
13
14Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
15Helps: #2319
16
17Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
18CVE: CVE-2021-27219
19Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
20Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
21
22---
23 gio/gwin32registrykey.c | 34 ++++++++++++++++++++++++++--------
24 2 files changed, 38 insertions(+), 16 deletions(-)
25
26diff --git a/gio/gwin32registrykey.c b/gio/gwin32registrykey.c
27index 548a94188..2eb67daf8 100644
28--- a/gio/gwin32registrykey.c
29+++ b/gio/gwin32registrykey.c
30@@ -127,16 +127,34 @@ typedef enum
31 G_WIN32_REGISTRY_UPDATED_PATH = 1,
32 } GWin32RegistryKeyUpdateFlag;
33
34+static gsize
35+g_utf16_len (const gunichar2 *str)
36+{
37+ gsize result;
38+
39+ for (result = 0; str[0] != 0; str++, result++)
40+ ;
41+
42+ return result;
43+}
44+
45 static gunichar2 *
46-g_wcsdup (const gunichar2 *str,
47- gssize str_size)
48+g_wcsdup (const gunichar2 *str, gssize str_len)
49 {
50- if (str_size == -1)
51- {
52- str_size = wcslen (str) + 1;
53- str_size *= sizeof (gunichar2);
54- }
55- return g_memdup (str, str_size);
56+ gsize str_len_unsigned;
57+ gsize str_size;
58+
59+ g_return_val_if_fail (str != NULL, NULL);
60+
61+ if (str_len < 0)
62+ str_len_unsigned = g_utf16_len (str);
63+ else
64+ str_len_unsigned = (gsize) str_len;
65+
66+ g_assert (str_len_unsigned <= G_MAXSIZE / sizeof (gunichar2) - 1);
67+ str_size = (str_len_unsigned + 1) * sizeof (gunichar2);
68+
69+ return g_memdup2 (str, str_size);
70 }
71
72 /**
73--
74GitLab
75
76
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-08.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-08.patch
new file mode 100644
index 0000000000..ffafc35c07
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-08.patch
@@ -0,0 +1,101 @@
1From ba8ca443051f93a74c0d03d62e70402036f967a5 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Thu, 4 Feb 2021 13:58:32 +0000
4Subject: [PATCH 08/11] gkeyfilesettingsbackend: Handle long keys when
5 converting paths
6
7Previously, the code in `convert_path()` could not handle keys longer
8than `G_MAXINT`, and would overflow if that was exceeded.
9
10Convert the code to use `gsize` and `g_memdup2()` throughout, and
11change from identifying the position of the final slash in the string
12using a signed offset `i`, to using a pointer to the character (and
13`strrchr()`). This allows the slash to be at any position in a
14`G_MAXSIZE`-long string, without sacrificing a bit of the offset for
15indicating whether a slash was found.
16
17Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
18Helps: #2319
19
20Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
21CVE: CVE-2021-27219
22Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
23Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
24
25---
26 gio/gkeyfilesettingsbackend.c | 21 ++++++++++-----------
27 1 file changed, 10 insertions(+), 11 deletions(-)
28
29diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c
30index cd5765afd..25b057672 100644
31--- a/gio/gkeyfilesettingsbackend.c
32+++ b/gio/gkeyfilesettingsbackend.c
33@@ -33,6 +33,7 @@
34 #include "gfilemonitor.h"
35 #include "gsimplepermission.h"
36 #include "gsettingsbackendinternal.h"
37+#include "gstrfuncsprivate.h"
38 #include "giomodule-priv.h"
39 #include "gportalsupport.h"
40
41@@ -145,8 +146,8 @@ convert_path (GKeyfileSettingsBackend *kfsb,
42 gchar **group,
43 gchar **basename)
44 {
45- gint key_len = strlen (key);
46- gint i;
47+ gsize key_len = strlen (key);
48+ const gchar *last_slash;
49
50 if (key_len < kfsb->prefix_len ||
51 memcmp (key, kfsb->prefix, kfsb->prefix_len) != 0)
52@@ -155,38 +156,36 @@ convert_path (GKeyfileSettingsBackend *kfsb,
53 key_len -= kfsb->prefix_len;
54 key += kfsb->prefix_len;
55
56- for (i = key_len; i >= 0; i--)
57- if (key[i] == '/')
58- break;
59+ last_slash = strrchr (key, '/');
60
61 if (kfsb->root_group)
62 {
63 /* if a root_group was specified, make sure the user hasn't given
64 * a path that ghosts that group name
65 */
66- if (i == kfsb->root_group_len && memcmp (key, kfsb->root_group, i) == 0)
67+ if (last_slash != NULL && (last_slash - key) == kfsb->root_group_len && memcmp (key, kfsb->root_group, last_slash - key) == 0)
68 return FALSE;
69 }
70 else
71 {
72 /* if no root_group was given, ensure that the user gave a path */
73- if (i == -1)
74+ if (last_slash == NULL)
75 return FALSE;
76 }
77
78 if (group)
79 {
80- if (i >= 0)
81+ if (last_slash != NULL)
82 {
83- *group = g_memdup (key, i + 1);
84- (*group)[i] = '\0';
85+ *group = g_memdup2 (key, (last_slash - key) + 1);
86+ (*group)[(last_slash - key)] = '\0';
87 }
88 else
89 *group = g_strdup (kfsb->root_group);
90 }
91
92 if (basename)
93- *basename = g_memdup (key + i + 1, key_len - i);
94+ *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key));
95
96 return TRUE;
97 }
98--
99GitLab
100
101
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-09.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-09.patch
new file mode 100644
index 0000000000..8efb7c720f
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-09.patch
@@ -0,0 +1,100 @@
1From 65ec7f4d6e8832c481f6e00e2eb007b9a60024ce Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Thu, 4 Feb 2021 14:00:53 +0000
4Subject: [PATCH 09/11] =?UTF-8?q?gsocket:=20Use=20gsize=20to=20track=20nat?=
5 =?UTF-8?q?ive=20sockaddr=E2=80=99s=20size?=
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10Don’t use an `int`, that’s potentially too small. In practical terms,
11this is not a problem, since no socket address is going to be that big.
12
13By making these changes we can use `g_memdup2()` without warnings,
14though. Fewer warnings is good.
15
16Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
17Helps: #2319
18
19Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
20CVE: CVE-2021-27219
21Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
22Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
23
24---
25 gio/gsocket.c | 16 ++++++++++------
26 1 file changed, 10 insertions(+), 6 deletions(-)
27
28--- a/gio/gsocket.c
29+++ b/gio/gsocket.c
30@@ -75,6 +75,7 @@
31 #include "gcredentialsprivate.h"
32 #include "glibintl.h"
33 #include "gioprivate.h"
34+#include "gstrfuncsprivate.h"
35
36 #ifdef G_OS_WIN32
37 /* For Windows XP runtime compatibility, but use the system's if_nametoindex() if available */
38@@ -174,7 +175,7 @@ static gboolean g_socket_datagram_ba
39 GError **error);
40
41 static GSocketAddress *
42-cache_recv_address (GSocket *socket, struct sockaddr *native, int native_len);
43+cache_recv_address (GSocket *socket, struct sockaddr *native, size_t native_len);
44
45 static gssize
46 g_socket_receive_message_with_timeout (GSocket *socket,
47@@ -260,7 +261,7 @@ struct _GSocketPrivate
48 struct {
49 GSocketAddress *addr;
50 struct sockaddr *native;
51- gint native_len;
52+ gsize native_len;
53 guint64 last_used;
54 } recv_addr_cache[RECV_ADDR_CACHE_SIZE];
55 };
56@@ -5259,14 +5260,14 @@ g_socket_send_messages_with_timeout (GSo
57 }
58
59 static GSocketAddress *
60-cache_recv_address (GSocket *socket, struct sockaddr *native, int native_len)
61+cache_recv_address (GSocket *socket, struct sockaddr *native, size_t native_len)
62 {
63 GSocketAddress *saddr;
64 gint i;
65 guint64 oldest_time = G_MAXUINT64;
66 gint oldest_index = 0;
67
68- if (native_len <= 0)
69+ if (native_len == 0)
70 return NULL;
71
72 saddr = NULL;
73@@ -5274,7 +5275,7 @@ cache_recv_address (GSocket *socket, str
74 {
75 GSocketAddress *tmp = socket->priv->recv_addr_cache[i].addr;
76 gpointer tmp_native = socket->priv->recv_addr_cache[i].native;
77- gint tmp_native_len = socket->priv->recv_addr_cache[i].native_len;
78+ gsize tmp_native_len = socket->priv->recv_addr_cache[i].native_len;
79
80 if (!tmp)
81 continue;
82@@ -5304,7 +5305,7 @@ cache_recv_address (GSocket *socket, str
83 g_free (socket->priv->recv_addr_cache[oldest_index].native);
84 }
85
86- socket->priv->recv_addr_cache[oldest_index].native = g_memdup (native, native_len);
87+ socket->priv->recv_addr_cache[oldest_index].native = g_memdup2 (native, native_len);
88 socket->priv->recv_addr_cache[oldest_index].native_len = native_len;
89 socket->priv->recv_addr_cache[oldest_index].addr = g_object_ref (saddr);
90 socket->priv->recv_addr_cache[oldest_index].last_used = g_get_monotonic_time ();
91@@ -5452,6 +5453,9 @@ g_socket_receive_message_with_timeout (G
92 /* do it */
93 while (1)
94 {
95+ /* addrlen has to be of type int because that’s how WSARecvFrom() is defined */
96+ G_STATIC_ASSERT (sizeof addr <= G_MAXINT);
97+
98 addrlen = sizeof addr;
99 if (address)
100 result = WSARecvFrom (socket->priv->fd,
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-10.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-10.patch
new file mode 100644
index 0000000000..63fda0b600
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-10.patch
@@ -0,0 +1,59 @@
1From 777b95a88f006d39d9fe6d3321db17e7b0d4b9a4 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Thu, 4 Feb 2021 14:07:39 +0000
4Subject: [PATCH 10/11] gtlspassword: Forbid very long TLS passwords
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9The public API `g_tls_password_set_value_full()` (and the vfunc it
10invokes) can only accept a `gssize` length. Ensure that nul-terminated
11strings passed to `g_tls_password_set_value()` can’t exceed that length.
12Use `g_memdup2()` to avoid an overflow if they’re longer than
13`G_MAXUINT` similarly.
14
15Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
16Helps: #2319
17
18Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
19CVE: CVE-2021-27219
20Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
21Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
22
23---
24 gio/gtlspassword.c | 10 ++++++++--
25 1 file changed, 8 insertions(+), 2 deletions(-)
26
27diff --git a/gio/gtlspassword.c b/gio/gtlspassword.c
28index 1e437a7b6..dbcec41a8 100644
29--- a/gio/gtlspassword.c
30+++ b/gio/gtlspassword.c
31@@ -23,6 +23,7 @@
32 #include "glibintl.h"
33
34 #include "gioenumtypes.h"
35+#include "gstrfuncsprivate.h"
36 #include "gtlspassword.h"
37
38 #include <string.h>
39@@ -287,9 +288,14 @@ g_tls_password_set_value (GTlsPassword *password,
40 g_return_if_fail (G_IS_TLS_PASSWORD (password));
41
42 if (length < 0)
43- length = strlen ((gchar *)value);
44+ {
45+ /* FIXME: g_tls_password_set_value_full() doesn’t support unsigned gsize */
46+ gsize length_unsigned = strlen ((gchar *) value);
47+ g_return_if_fail (length_unsigned > G_MAXSSIZE);
48+ length = (gssize) length_unsigned;
49+ }
50
51- g_tls_password_set_value_full (password, g_memdup (value, length), length, g_free);
52+ g_tls_password_set_value_full (password, g_memdup2 (value, (gsize) length), length, g_free);
53 }
54
55 /**
56--
57GitLab
58
59
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-11.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-11.patch
new file mode 100644
index 0000000000..a620a49269
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-11.patch
@@ -0,0 +1,63 @@
1From ecdf91400e9a538695a0895b95ad7e8abcdf1749 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Thu, 4 Feb 2021 14:09:40 +0000
4Subject: [PATCH 11/11] giochannel: Forbid very long line terminator strings
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9The public API `GIOChannel.line_term_len` is only a `guint`. Ensure that
10nul-terminated strings passed to `g_io_channel_set_line_term()` can’t
11exceed that length. Use `g_memdup2()` to avoid a warning (`g_memdup()`
12is due to be deprecated), but not to avoid a bug, since it’s also
13limited to `G_MAXUINT`.
14
15Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
16Helps: #2319
17
18Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
19CVE: CVE-2021-27219
20Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
21Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
22
23---
24 glib/giochannel.c | 17 +++++++++++++----
25 1 file changed, 13 insertions(+), 4 deletions(-)
26
27diff --git a/glib/giochannel.c b/glib/giochannel.c
28index c6a89d6e0..4dec20f77 100644
29--- a/glib/giochannel.c
30+++ b/glib/giochannel.c
31@@ -887,16 +887,25 @@ g_io_channel_set_line_term (GIOChannel *channel,
32 const gchar *line_term,
33 gint length)
34 {
35+ guint length_unsigned;
36+
37 g_return_if_fail (channel != NULL);
38 g_return_if_fail (line_term == NULL || length != 0); /* Disallow "" */
39
40 if (line_term == NULL)
41- length = 0;
42- else if (length < 0)
43- length = strlen (line_term);
44+ length_unsigned = 0;
45+ else if (length >= 0)
46+ length_unsigned = (guint) length;
47+ else
48+ {
49+ /* FIXME: We’re constrained by line_term_len being a guint here */
50+ gsize length_size = strlen (line_term);
51+ g_return_if_fail (length_size > G_MAXUINT);
52+ length_unsigned = (guint) length_size;
53+ }
54
55 g_free (channel->line_term);
56- channel->line_term = line_term ? g_memdup (line_term, length) : NULL;
57+ channel->line_term = line_term ? g_memdup2 (line_term, length_unsigned) : NULL;
58 channel->line_term_len = length;
59 }
60
61--
62GitLab
63
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-1.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-1.patch
new file mode 100644
index 0000000000..3047062f54
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-1.patch
@@ -0,0 +1,36 @@
1From f8273b9aded135fe07094faebd527e43851aaf6e Mon Sep 17 00:00:00 2001
2From: "Jan Alexander Steffens (heftig)" <jan.steffens@gmail.com>
3Date: Sun, 7 Feb 2021 23:32:40 +0100
4Subject: [PATCH 1/5] giochannel: Fix length_size bounds check
5
6The inverted condition is an obvious error introduced by ecdf91400e9a.
7
8Fixes https://gitlab.gnome.org/GNOME/glib/-/issues/2323
9
10(cherry picked from commit a149bf2f9030168051942124536e303af8ba6176)
11
12Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
13CVE: CVE-2021-27219
14Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
15
16---
17 glib/giochannel.c | 2 +-
18 1 file changed, 1 insertion(+), 1 deletion(-)
19
20diff --git a/glib/giochannel.c b/glib/giochannel.c
21index 4dec20f77..c3f3102ff 100644
22--- a/glib/giochannel.c
23+++ b/glib/giochannel.c
24@@ -896,7 +896,7 @@ g_io_channel_set_line_term (GIOChannel *channel,
25 {
26 /* FIXME: We’re constrained by line_term_len being a guint here */
27 gsize length_size = strlen (line_term);
28- g_return_if_fail (length_size > G_MAXUINT);
29+ g_return_if_fail (length_size <= G_MAXUINT);
30 length_unsigned = (guint) length_size;
31 }
32
33--
34GitLab
35
36
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-2.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-2.patch
new file mode 100644
index 0000000000..2ba26075df
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-2.patch
@@ -0,0 +1,38 @@
1From e069c50467712e6d607822afd6b6c15c2c343dff Mon Sep 17 00:00:00 2001
2From: Simon McVittie <smcv@collabora.com>
3Date: Mon, 8 Feb 2021 10:34:50 +0000
4Subject: [PATCH 2/5] giochannel: Don't store negative line_term_len in
5 GIOChannel struct
6
7Adding test coverage indicated that this was another bug in 0cc11f74.
8
9Fixes: 0cc11f74 "giochannel: Forbid very long line terminator strings"
10Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/2323
11Signed-off-by: Simon McVittie <smcv@collabora.com>
12(cherry picked from commit 5dc8b0014c03e7491d93b90275ab442e888a9628)
13
14Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
15CVE: CVE-2021-27219
16Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
17
18---
19 glib/giochannel.c | 2 +-
20 1 file changed, 1 insertion(+), 1 deletion(-)
21
22diff --git a/glib/giochannel.c b/glib/giochannel.c
23index c3f3102ff..19bb06ba6 100644
24--- a/glib/giochannel.c
25+++ b/glib/giochannel.c
26@@ -902,7 +902,7 @@ g_io_channel_set_line_term (GIOChannel *channel,
27
28 g_free (channel->line_term);
29 channel->line_term = line_term ? g_memdup2 (line_term, length_unsigned) : NULL;
30- channel->line_term_len = length;
31+ channel->line_term_len = length_unsigned;
32 }
33
34 /**
35--
36GitLab
37
38
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-4.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-4.patch
new file mode 100644
index 0000000000..2c388b4bbb
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-4.patch
@@ -0,0 +1,38 @@
1From 4506d1859a863087598c8d122740bae25b65b099 Mon Sep 17 00:00:00 2001
2From: Simon McVittie <smcv@collabora.com>
3Date: Mon, 8 Feb 2021 10:04:48 +0000
4Subject: [PATCH 4/5] gtlspassword: Fix inverted assertion
5
6The intention here was to assert that the length of the password fits
7in a gssize. Passwords more than half the size of virtual memory are
8probably excessive.
9
10Fixes: a8b204ff "gtlspassword: Forbid very long TLS passwords"
11Signed-off-by: Simon McVittie <smcv@collabora.com>
12(cherry picked from commit 61bb52ec42de1082bfb06ce1c737fc295bfe60b8)
13
14Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
15CVE: CVE-2021-27219
16Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
17
18---
19 gio/gtlspassword.c | 2 +-
20 1 file changed, 1 insertion(+), 1 deletion(-)
21
22diff --git a/gio/gtlspassword.c b/gio/gtlspassword.c
23index dbcec41a8..bd86a6dfe 100644
24--- a/gio/gtlspassword.c
25+++ b/gio/gtlspassword.c
26@@ -291,7 +291,7 @@ g_tls_password_set_value (GTlsPassword *password,
27 {
28 /* FIXME: g_tls_password_set_value_full() doesn’t support unsigned gsize */
29 gsize length_unsigned = strlen ((gchar *) value);
30- g_return_if_fail (length_unsigned > G_MAXSSIZE);
31+ g_return_if_fail (length_unsigned <= G_MAXSSIZE);
32 length = (gssize) length_unsigned;
33 }
34
35--
36GitLab
37
38
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-5.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-5.patch
new file mode 100644
index 0000000000..356e986fe0
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg1-5.patch
@@ -0,0 +1,100 @@
1From 3d1550354c3c6a8491c39881752d51cb7515f2c2 Mon Sep 17 00:00:00 2001
2From: Simon McVittie <smcv@collabora.com>
3Date: Mon, 8 Feb 2021 10:22:39 +0000
4Subject: [PATCH 5/5] tls-interaction: Add test coverage for various ways to
5 set the password
6
7Signed-off-by: Simon McVittie <smcv@collabora.com>
8(cherry picked from commit df4501316ca3903072400504a5ea76498db19538)
9
10Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
11CVE: CVE-2021-27219
12Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
13
14---
15 gio/tests/tls-interaction.c | 55 +++++++++++++++++++++++++++++++++++++
16 1 file changed, 55 insertions(+)
17
18diff --git a/gio/tests/tls-interaction.c b/gio/tests/tls-interaction.c
19index 4f0737d7e..5661e8e0d 100644
20--- a/gio/tests/tls-interaction.c
21+++ b/gio/tests/tls-interaction.c
22@@ -174,6 +174,38 @@ test_interaction_ask_password_finish_failure (GTlsInteraction *interaction,
23 }
24
25
26+/* Return a copy of @str that is allocated in a silly way, to exercise
27+ * custom free-functions. The returned pointer points to a copy of @str
28+ * in a buffer of the form "BEFORE \0 str \0 AFTER". */
29+static guchar *
30+special_dup (const char *str)
31+{
32+ GString *buf = g_string_new ("BEFORE");
33+ guchar *ret;
34+
35+ g_string_append_c (buf, '\0');
36+ g_string_append (buf, str);
37+ g_string_append_c (buf, '\0');
38+ g_string_append (buf, "AFTER");
39+ ret = (guchar *) g_string_free (buf, FALSE);
40+ return ret + strlen ("BEFORE") + 1;
41+}
42+
43+
44+/* Free a copy of @str that was made with special_dup(), after asserting
45+ * that it has not been corrupted. */
46+static void
47+special_free (gpointer p)
48+{
49+ gchar *s = p;
50+ gchar *buf = s - strlen ("BEFORE") - 1;
51+
52+ g_assert_cmpstr (buf, ==, "BEFORE");
53+ g_assert_cmpstr (s + strlen (s) + 1, ==, "AFTER");
54+ g_free (buf);
55+}
56+
57+
58 static GTlsInteractionResult
59 test_interaction_ask_password_sync_success (GTlsInteraction *interaction,
60 GTlsPassword *password,
61@@ -181,6 +213,8 @@ test_interaction_ask_password_sync_success (GTlsInteraction *interaction,
62 GError **error)
63 {
64 TestInteraction *self;
65+ const guchar *value;
66+ gsize len;
67
68 g_assert (TEST_IS_INTERACTION (interaction));
69 self = TEST_INTERACTION (interaction);
70@@ -192,6 +226,27 @@ test_interaction_ask_password_sync_success (GTlsInteraction *interaction,
71 g_assert (error != NULL);
72 g_assert (*error == NULL);
73
74+ /* Exercise different ways to set the value */
75+ g_tls_password_set_value (password, (const guchar *) "foo", 4);
76+ len = 0;
77+ value = g_tls_password_get_value (password, &len);
78+ g_assert_cmpmem (value, len, "foo", 4);
79+
80+ g_tls_password_set_value (password, (const guchar *) "bar", -1);
81+ len = 0;
82+ value = g_tls_password_get_value (password, &len);
83+ g_assert_cmpmem (value, len, "bar", 3);
84+
85+ g_tls_password_set_value_full (password, special_dup ("baa"), 4, special_free);
86+ len = 0;
87+ value = g_tls_password_get_value (password, &len);
88+ g_assert_cmpmem (value, len, "baa", 4);
89+
90+ g_tls_password_set_value_full (password, special_dup ("baz"), -1, special_free);
91+ len = 0;
92+ value = g_tls_password_get_value (password, &len);
93+ g_assert_cmpmem (value, len, "baz", 3);
94+
95 /* Don't do this in real life. Include a null terminator for testing */
96 g_tls_password_set_value (password, (const guchar *)"the password", 13);
97 return G_TLS_INTERACTION_HANDLED;
98--
99GitLab
100
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg2-1.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg2-1.patch
new file mode 100644
index 0000000000..dd43689aae
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg2-1.patch
@@ -0,0 +1,49 @@
1From cb9ee701ef46c1819eed4e2a4dc181682bdfc176 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Wed, 10 Feb 2021 21:16:39 +0000
4Subject: [PATCH 1/3] gkeyfilesettingsbackend: Fix basename handling when group
5 is unset
6
7Fix an effective regression in commit
87781a9cbd2fd0aa84bee0f4eee88470640ff6706, which happens when
9`convert_path()` is called with a `key` which contains no slashes. In
10that case, the `key` is entirely the `basename`.
11
12Prior to commit 7781a9cb, the code worked through a fluke of `i == -1`
13cancelling out with the various additions in the `g_memdup()` call, and
14effectively resulting in `g_strdup (key)`.
15
16Spotted by Guido Berhoerster.
17
18Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
19
20Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
21CVE: CVE-2021-27219
22Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
23
24---
25 gio/gkeyfilesettingsbackend.c | 7 ++++++-
26 1 file changed, 6 insertions(+), 1 deletion(-)
27
28diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c
29index 25b057672..861c3a661 100644
30--- a/gio/gkeyfilesettingsbackend.c
31+++ b/gio/gkeyfilesettingsbackend.c
32@@ -185,7 +185,12 @@ convert_path (GKeyfileSettingsBackend *kfsb,
33 }
34
35 if (basename)
36- *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key));
37+ {
38+ if (last_slash != NULL)
39+ *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key));
40+ else
41+ *basename = g_strdup (key);
42+ }
43
44 return TRUE;
45 }
46--
47GitLab
48
49
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg2-2.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg2-2.patch
new file mode 100644
index 0000000000..04503641c3
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg2-2.patch
@@ -0,0 +1,43 @@
1From 31e0d403ba635dbbacbfbff74295e5db02558d76 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Wed, 10 Feb 2021 21:19:30 +0000
4Subject: [PATCH 2/3] gkeyfilesettingsbackend: Disallow empty key or group
5 names
6
7These should never have been allowed; they will result in precondition
8failures from the `GKeyFile` later on in the code.
9
10A test will be added for this shortly.
11
12Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
13
14Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
15CVE: CVE-2021-27219
16Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
17
18---
19 gio/gkeyfilesettingsbackend.c | 7 +++++++
20 1 file changed, 7 insertions(+)
21
22diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c
23index 861c3a661..de216e615 100644
24--- a/gio/gkeyfilesettingsbackend.c
25+++ b/gio/gkeyfilesettingsbackend.c
26@@ -158,6 +158,13 @@ convert_path (GKeyfileSettingsBackend *kfsb,
27
28 last_slash = strrchr (key, '/');
29
30+ /* Disallow empty group names or key names */
31+ if (key_len == 0 ||
32+ (last_slash != NULL &&
33+ (*(last_slash + 1) == '\0' ||
34+ last_slash == key)))
35+ return FALSE;
36+
37 if (kfsb->root_group)
38 {
39 /* if a root_group was specified, make sure the user hasn't given
40--
41GitLab
42
43
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg2-3.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg2-3.patch
new file mode 100644
index 0000000000..65f59287a8
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-27219-reg2-3.patch
@@ -0,0 +1,232 @@
1Backport of:
2
3From 221c26685354dea2b2732df94404e8e5e77a1591 Mon Sep 17 00:00:00 2001
4From: Philip Withnall <pwithnall@endlessos.org>
5Date: Wed, 10 Feb 2021 21:21:36 +0000
6Subject: [PATCH 3/3] tests: Add tests for key name handling in the keyfile
7 backend
8
9This tests the two recent commits.
10
11Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
12
13Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
14CVE: CVE-2021-27219
15Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
16
17---
18 gio/tests/gsettings.c | 170 +++++++++++++++++++++++++++++++++++++++++-
19 1 file changed, 169 insertions(+), 1 deletion(-)
20
21--- a/gio/tests/gsettings.c
22+++ b/gio/tests/gsettings.c
23@@ -1,3 +1,4 @@
24+#include <errno.h>
25 #include <stdlib.h>
26 #include <locale.h>
27 #include <libintl.h>
28@@ -1740,6 +1741,14 @@ key_changed_cb (GSettings *settings, con
29 (*b) = TRUE;
30 }
31
32+typedef struct
33+{
34+ const gchar *path;
35+ const gchar *root_group;
36+ const gchar *keyfile_group;
37+ const gchar *root_path;
38+} KeyfileTestData;
39+
40 /*
41 * Test that using a keyfile works
42 */
43@@ -1834,7 +1843,11 @@ test_keyfile (Fixture *fixture,
44 g_free (str);
45
46 g_settings_set (settings, "farewell", "s", "cheerio");
47-
48+
49+ /* Check that empty keys/groups are not allowed. */
50+ g_assert_false (g_settings_is_writable (settings, ""));
51+ g_assert_false (g_settings_is_writable (settings, "/"));
52+
53 /* When executing as root, changing the mode of the keyfile will have
54 * no effect on the writability of the settings.
55 */
56@@ -1866,6 +1879,149 @@ test_keyfile (Fixture *fixture,
57 g_free (keyfile_path);
58 }
59
60+/*
61+ * Test that using a keyfile works with a schema with no path set.
62+ */
63+static void
64+test_keyfile_no_path (Fixture *fixture,
65+ gconstpointer user_data)
66+{
67+ const KeyfileTestData *test_data = user_data;
68+ GSettingsBackend *kf_backend;
69+ GSettings *settings;
70+ GKeyFile *keyfile;
71+ gboolean writable;
72+ gchar *key = NULL;
73+ GError *error = NULL;
74+ gchar *keyfile_path = NULL, *store_path = NULL;
75+
76+ keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL);
77+ store_path = g_build_filename (keyfile_path, "gsettings.store", NULL);
78+ kf_backend = g_keyfile_settings_backend_new (store_path, test_data->root_path, test_data->root_group);
79+ settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, test_data->path);
80+ g_object_unref (kf_backend);
81+
82+ g_settings_reset (settings, "test-boolean");
83+ g_assert_true (g_settings_get_boolean (settings, "test-boolean"));
84+
85+ writable = g_settings_is_writable (settings, "test-boolean");
86+ g_assert_true (writable);
87+ g_settings_set (settings, "test-boolean", "b", FALSE);
88+
89+ g_assert_false (g_settings_get_boolean (settings, "test-boolean"));
90+
91+ g_settings_delay (settings);
92+ g_settings_set (settings, "test-boolean", "b", TRUE);
93+ g_settings_apply (settings);
94+
95+ keyfile = g_key_file_new ();
96+ g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL));
97+
98+ g_assert_true (g_key_file_get_boolean (keyfile, test_data->keyfile_group, "test-boolean", NULL));
99+
100+ g_key_file_free (keyfile);
101+
102+ g_settings_reset (settings, "test-boolean");
103+ g_settings_apply (settings);
104+ keyfile = g_key_file_new ();
105+ g_assert_true (g_key_file_load_from_file (keyfile, store_path, 0, NULL));
106+
107+ g_assert_false (g_key_file_get_string (keyfile, test_data->keyfile_group, "test-boolean", &error));
108+ g_assert_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND);
109+ g_clear_error (&error);
110+
111+ /* Check that empty keys/groups are not allowed. */
112+ g_assert_false (g_settings_is_writable (settings, ""));
113+ g_assert_false (g_settings_is_writable (settings, "/"));
114+
115+ /* Keys which ghost the root group name are not allowed. This can only be
116+ * tested when the path is `/` as otherwise it acts as a prefix and prevents
117+ * any ghosting. */
118+ if (g_str_equal (test_data->path, "/"))
119+ {
120+ key = g_strdup_printf ("%s/%s", test_data->root_group, "");
121+ g_assert_false (g_settings_is_writable (settings, key));
122+ g_free (key);
123+
124+ key = g_strdup_printf ("%s/%s", test_data->root_group, "/");
125+ g_assert_false (g_settings_is_writable (settings, key));
126+ g_free (key);
127+
128+ key = g_strdup_printf ("%s/%s", test_data->root_group, "test-boolean");
129+ g_assert_false (g_settings_is_writable (settings, key));
130+ g_free (key);
131+ }
132+
133+ g_key_file_free (keyfile);
134+ g_object_unref (settings);
135+
136+ /* Clean up the temporary directory. */
137+ g_assert_cmpint (g_chmod (keyfile_path, 0777) == 0 ? 0 : errno, ==, 0);
138+ g_assert_cmpint (g_remove (store_path) == 0 ? 0 : errno, ==, 0);
139+ g_assert_cmpint (g_rmdir (keyfile_path) == 0 ? 0 : errno, ==, 0);
140+ g_free (store_path);
141+ g_free (keyfile_path);
142+}
143+
144+/*
145+ * Test that a keyfile rejects writes to keys outside its root path.
146+ */
147+static void
148+test_keyfile_outside_root_path (Fixture *fixture,
149+ gconstpointer user_data)
150+{
151+ GSettingsBackend *kf_backend;
152+ GSettings *settings;
153+ gchar *keyfile_path = NULL, *store_path = NULL;
154+
155+ keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL);
156+ store_path = g_build_filename (keyfile_path, "gsettings.store", NULL);
157+ kf_backend = g_keyfile_settings_backend_new (store_path, "/tests/basic-types/", "root");
158+ settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, "/tests/");
159+ g_object_unref (kf_backend);
160+
161+ g_assert_false (g_settings_is_writable (settings, "test-boolean"));
162+
163+ g_object_unref (settings);
164+
165+ /* Clean up the temporary directory. The keyfile probably doesn’t exist, so
166+ * don’t error on failure. */
167+ g_remove (store_path);
168+ g_assert_cmpint (g_rmdir (keyfile_path) == 0 ? 0 : errno, ==, 0);
169+ g_free (store_path);
170+ g_free (keyfile_path);
171+}
172+
173+/*
174+ * Test that a keyfile rejects writes to keys in the root if no root group is set.
175+ */
176+static void
177+test_keyfile_no_root_group (Fixture *fixture,
178+ gconstpointer user_data)
179+{
180+ GSettingsBackend *kf_backend;
181+ GSettings *settings;
182+ gchar *keyfile_path = NULL, *store_path = NULL;
183+
184+ keyfile_path = g_build_filename (fixture->tmp_dir, "keyfile", NULL);
185+ store_path = g_build_filename (keyfile_path, "gsettings.store", NULL);
186+ kf_backend = g_keyfile_settings_backend_new (store_path, "/", NULL);
187+ settings = g_settings_new_with_backend_and_path ("org.gtk.test.no-path", kf_backend, "/");
188+ g_object_unref (kf_backend);
189+
190+ g_assert_false (g_settings_is_writable (settings, "test-boolean"));
191+ g_assert_true (g_settings_is_writable (settings, "child/test-boolean"));
192+
193+ g_object_unref (settings);
194+
195+ /* Clean up the temporary directory. The keyfile probably doesn’t exist, so
196+ * don’t error on failure. */
197+ g_remove (store_path);
198+ g_assert_cmpint (g_rmdir (keyfile_path) == 0 ? 0 : errno, ==, 0);
199+ g_free (store_path);
200+ g_free (keyfile_path);
201+}
202+
203 /* Test that getting child schemas works
204 */
205 static void
206@@ -2844,6 +3000,14 @@ main (int argc, char *argv[])
207 gchar *override_text;
208 gchar *enums;
209 gint result;
210+ const KeyfileTestData keyfile_test_data_explicit_path = { "/tests/", "root", "tests", "/" };
211+ const KeyfileTestData keyfile_test_data_empty_path = { "/", "root", "root", "/" };
212+ const KeyfileTestData keyfile_test_data_long_path = {
213+ "/tests/path/is/very/long/and/this/makes/some/comparisons/take/a/different/branch/",
214+ "root",
215+ "tests/path/is/very/long/and/this/makes/some/comparisons/take/a/different/branch",
216+ "/"
217+ };
218
219 /* Meson build sets this */
220 #ifdef TEST_LOCALE_PATH
221@@ -2967,6 +3131,11 @@ main (int argc, char *argv[])
222 }
223
224 g_test_add ("/gsettings/keyfile", Fixture, NULL, setup, test_keyfile, teardown);
225+ g_test_add ("/gsettings/keyfile/explicit-path", Fixture, &keyfile_test_data_explicit_path, setup, test_keyfile_no_path, teardown);
226+ g_test_add ("/gsettings/keyfile/empty-path", Fixture, &keyfile_test_data_empty_path, setup, test_keyfile_no_path, teardown);
227+ g_test_add ("/gsettings/keyfile/long-path", Fixture, &keyfile_test_data_long_path, setup, test_keyfile_no_path, teardown);
228+ g_test_add ("/gsettings/keyfile/outside-root-path", Fixture, NULL, setup, test_keyfile_outside_root_path, teardown);
229+ g_test_add ("/gsettings/keyfile/no-root-group", Fixture, NULL, setup, test_keyfile_no_root_group, teardown);
230 g_test_add_func ("/gsettings/child-schema", test_child_schema);
231 g_test_add_func ("/gsettings/strinfo", test_strinfo);
232 g_test_add_func ("/gsettings/enums", test_enums);
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-1.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-1.patch
new file mode 100644
index 0000000000..c89ca20726
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-1.patch
@@ -0,0 +1,27 @@
1From 78420a75aeb70569a8cd79fa0fea7b786b6f785f Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Wed, 24 Feb 2021 17:33:38 +0000
4Subject: [PATCH 1/5] glocalfileoutputstream: Fix a typo in a comment
5
6Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
7
8Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
9CVE: CVE-2021-28153
10Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
11Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
12
13---
14 gio/glocalfileoutputstream.c | 2 +-
15 1 file changed, 1 insertion(+), 1 deletion(-)
16
17--- a/gio/glocalfileoutputstream.c
18+++ b/gio/glocalfileoutputstream.c
19@@ -851,7 +851,7 @@ handle_overwrite_open (const char *fi
20 mode = mode_from_flags_or_info (flags, reference_info);
21
22 /* We only need read access to the original file if we are creating a backup.
23- * We also add O_CREATE to avoid a race if the file was just removed */
24+ * We also add O_CREAT to avoid a race if the file was just removed */
25 if (create_backup || readable)
26 open_flags = O_RDWR | O_CREAT | O_BINARY;
27 else
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-2.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-2.patch
new file mode 100644
index 0000000000..8a35bab4de
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-2.patch
@@ -0,0 +1,42 @@
1From 32d3d02a50e7dcec5f4cf7908e7ac88d575d8fc5 Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Wed, 24 Feb 2021 17:34:32 +0000
4Subject: [PATCH 2/5] tests: Stop using g_test_bug_base() in file tests
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9Since a following commit is going to add a new test which references
10Gitlab, so it’s best to move the URI bases inside the test cases.
11
12Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
13
14Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
15CVE: CVE-2021-28153
16Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
17Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
18
19---
20 gio/tests/file.c | 4 +---
21 1 file changed, 1 insertion(+), 3 deletions(-)
22
23--- a/gio/tests/file.c
24+++ b/gio/tests/file.c
25@@ -685,7 +685,7 @@ test_replace_cancel (void)
26 guint count;
27 GError *error = NULL;
28
29- g_test_bug ("629301");
30+ g_test_bug ("https://bugzilla.gnome.org/629301");
31
32 path = g_dir_make_tmp ("g_file_replace_cancel_XXXXXX", &error);
33 g_assert_no_error (error);
34@@ -1784,8 +1784,6 @@ main (int argc, char *argv[])
35 {
36 g_test_init (&argc, &argv, NULL);
37
38- g_test_bug_base ("http://bugzilla.gnome.org/");
39-
40 g_test_add_func ("/file/basic", test_basic);
41 g_test_add_func ("/file/build-filename", test_build_filename);
42 g_test_add_func ("/file/parent", test_parent);
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-3.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-3.patch
new file mode 100644
index 0000000000..a82febd26e
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-3.patch
@@ -0,0 +1,57 @@
1Backport of:
2
3From ce0eb088a68171eed3ac217cb92a72e36eb57d1b Mon Sep 17 00:00:00 2001
4From: Philip Withnall <pwithnall@endlessos.org>
5Date: Wed, 10 Mar 2021 16:05:55 +0000
6Subject: [PATCH 3/5] glocalfileoutputstream: Factor out a flag check
7
8This clarifies the code a little. It introduces no functional changes.
9
10Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
11
12Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
13CVE: CVE-2021-28153
14Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
15Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
16
17---
18 gio/glocalfileoutputstream.c | 7 ++++---
19 1 file changed, 4 insertions(+), 3 deletions(-)
20
21--- a/gio/glocalfileoutputstream.c
22+++ b/gio/glocalfileoutputstream.c
23@@ -847,6 +847,7 @@ handle_overwrite_open (const char *fi
24 int res;
25 int mode;
26 int errsv;
27+ gboolean replace_destination_set = (flags & G_FILE_CREATE_REPLACE_DESTINATION);
28
29 mode = mode_from_flags_or_info (flags, reference_info);
30
31@@ -954,7 +955,7 @@ handle_overwrite_open (const char *fi
32 * to a backup file and rewrite the contents of the file.
33 */
34
35- if ((flags & G_FILE_CREATE_REPLACE_DESTINATION) ||
36+ if (replace_destination_set ||
37 (!(original_stat.st_nlink > 1) && !is_symlink))
38 {
39 char *dirname, *tmp_filename;
40@@ -973,7 +974,7 @@ handle_overwrite_open (const char *fi
41
42 /* try to keep permissions (unless replacing) */
43
44- if ( ! (flags & G_FILE_CREATE_REPLACE_DESTINATION) &&
45+ if (!replace_destination_set &&
46 (
47 #ifdef HAVE_FCHOWN
48 fchown (tmpfd, original_stat.st_uid, original_stat.st_gid) == -1 ||
49@@ -1112,7 +1113,7 @@ handle_overwrite_open (const char *fi
50 }
51 }
52
53- if (flags & G_FILE_CREATE_REPLACE_DESTINATION)
54+ if (replace_destination_set)
55 {
56 g_close (fd, NULL);
57
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-4.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-4.patch
new file mode 100644
index 0000000000..5b106e8474
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-4.patch
@@ -0,0 +1,265 @@
1Backport of:
2
3From 317b3b587058a05dca95d56dac26568c5b098d33 Mon Sep 17 00:00:00 2001
4From: Philip Withnall <pwithnall@endlessos.org>
5Date: Wed, 24 Feb 2021 17:36:07 +0000
6Subject: [PATCH 4/5] glocalfileoutputstream: Fix CREATE_REPLACE_DESTINATION
7 with symlinks
8MIME-Version: 1.0
9Content-Type: text/plain; charset=UTF-8
10Content-Transfer-Encoding: 8bit
11
12The `G_FILE_CREATE_REPLACE_DESTINATION` flag is equivalent to unlinking
13the destination file and re-creating it from scratch. That did
14previously work, but in the process the code would call `open(O_CREAT)`
15on the file. If the file was a dangling symlink, this would create the
16destination file (empty). That’s not an intended side-effect, and has
17security implications if the symlink is controlled by a lower-privileged
18process.
19
20Fix that by not opening the destination file if it’s a symlink, and
21adjusting the rest of the code to cope with
22 - the fact that `fd == -1` is not an error iff `is_symlink` is true,
23 - and that `original_stat` will contain the `lstat()` results for the
24 symlink now, rather than the `stat()` results for its target (again,
25 iff `is_symlink` is true).
26
27This means that the target of the dangling symlink is no longer created,
28which was the bug. The symlink itself continues to be replaced (as
29before) with the new file — this is the intended behaviour of
30`g_file_replace()`.
31
32The behaviour for non-symlink cases, or cases where the symlink was not
33dangling, should be unchanged.
34
35Includes a unit test.
36
37Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
38
39Fixes: #2325
40
41Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
42CVE: CVE-2021-28153
43Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
44Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
45
46---
47 gio/glocalfileoutputstream.c | 77 ++++++++++++++++++-------
48 gio/tests/file.c | 108 +++++++++++++++++++++++++++++++++++
49 2 files changed, 163 insertions(+), 22 deletions(-)
50
51--- a/gio/glocalfileoutputstream.c
52+++ b/gio/glocalfileoutputstream.c
53@@ -875,16 +875,22 @@ handle_overwrite_open (const char *fi
54 /* Could be a symlink, or it could be a regular ELOOP error,
55 * but then the next open will fail too. */
56 is_symlink = TRUE;
57- fd = g_open (filename, open_flags, mode);
58+ if (!replace_destination_set)
59+ fd = g_open (filename, open_flags, mode);
60 }
61-#else
62- fd = g_open (filename, open_flags, mode);
63- errsv = errno;
64+#else /* if !O_NOFOLLOW */
65 /* This is racy, but we do it as soon as possible to minimize the race */
66 is_symlink = g_file_test (filename, G_FILE_TEST_IS_SYMLINK);
67+
68+ if (!is_symlink || !replace_destination_set)
69+ {
70+ fd = g_open (filename, open_flags, mode);
71+ errsv = errno;
72+ }
73 #endif
74
75- if (fd == -1)
76+ if (fd == -1 &&
77+ (!is_symlink || !replace_destination_set))
78 {
79 char *display_name = g_filename_display_name (filename);
80 g_set_error (error, G_IO_ERROR,
81@@ -898,7 +904,14 @@ handle_overwrite_open (const char *fi
82 #ifdef G_OS_WIN32
83 res = GLIB_PRIVATE_CALL (g_win32_fstat) (fd, &original_stat);
84 #else
85- res = fstat (fd, &original_stat);
86+ if (!is_symlink)
87+ {
88+ res = fstat (fd, &original_stat);
89+ }
90+ else
91+ {
92+ res = lstat (filename, &original_stat);
93+ }
94 #endif
95 errsv = errno;
96
97@@ -917,16 +930,27 @@ handle_overwrite_open (const char *fi
98 if (!S_ISREG (original_stat.st_mode))
99 {
100 if (S_ISDIR (original_stat.st_mode))
101- g_set_error_literal (error,
102- G_IO_ERROR,
103- G_IO_ERROR_IS_DIRECTORY,
104- _("Target file is a directory"));
105- else
106- g_set_error_literal (error,
107+ {
108+ g_set_error_literal (error,
109+ G_IO_ERROR,
110+ G_IO_ERROR_IS_DIRECTORY,
111+ _("Target file is a directory"));
112+ goto err_out;
113+ }
114+ else if (!is_symlink ||
115+#ifdef S_ISLNK
116+ !S_ISLNK (original_stat.st_mode)
117+#else
118+ FALSE
119+#endif
120+ )
121+ {
122+ g_set_error_literal (error,
123 G_IO_ERROR,
124 G_IO_ERROR_NOT_REGULAR_FILE,
125 _("Target file is not a regular file"));
126- goto err_out;
127+ goto err_out;
128+ }
129 }
130
131 if (etag != NULL)
132@@ -1007,7 +1031,8 @@ handle_overwrite_open (const char *fi
133 }
134 }
135
136- g_close (fd, NULL);
137+ if (fd >= 0)
138+ g_close (fd, NULL);
139 *temp_filename = tmp_filename;
140 return tmpfd;
141 }
142--- a/gio/tests/file.c
143+++ b/gio/tests/file.c
144@@ -804,6 +804,113 @@ test_replace_cancel (void)
145 g_object_unref (tmpdir);
146 }
147
148+static void
149+test_replace_symlink (void)
150+{
151+#ifdef G_OS_UNIX
152+ gchar *tmpdir_path = NULL;
153+ GFile *tmpdir = NULL, *source_file = NULL, *target_file = NULL;
154+ GFileOutputStream *stream = NULL;
155+ const gchar *new_contents = "this is a test message which should be written to source and not target";
156+ gsize n_written;
157+ GFileEnumerator *enumerator = NULL;
158+ GFileInfo *info = NULL;
159+ gchar *contents = NULL;
160+ gsize length = 0;
161+ GError *local_error = NULL;
162+
163+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2325");
164+ g_test_summary ("Test that G_FILE_CREATE_REPLACE_DESTINATION doesn’t follow symlinks");
165+
166+ /* Create a fresh, empty working directory. */
167+ tmpdir_path = g_dir_make_tmp ("g_file_replace_symlink_XXXXXX", &local_error);
168+ g_assert_no_error (local_error);
169+ tmpdir = g_file_new_for_path (tmpdir_path);
170+
171+ g_test_message ("Using temporary directory %s", tmpdir_path);
172+ g_free (tmpdir_path);
173+
174+ /* Create symlink `source` which points to `target`. */
175+ source_file = g_file_get_child (tmpdir, "source");
176+ target_file = g_file_get_child (tmpdir, "target");
177+ g_file_make_symbolic_link (source_file, "target", NULL, &local_error);
178+ g_assert_no_error (local_error);
179+
180+ /* Ensure that `target` doesn’t exist */
181+ g_assert_false (g_file_query_exists (target_file, NULL));
182+
183+ /* Replace the `source` symlink with a regular file using
184+ * %G_FILE_CREATE_REPLACE_DESTINATION, which should replace it *without*
185+ * following the symlink */
186+ stream = g_file_replace (source_file, NULL, FALSE /* no backup */,
187+ G_FILE_CREATE_REPLACE_DESTINATION, NULL, &local_error);
188+ g_assert_no_error (local_error);
189+
190+ g_output_stream_write_all (G_OUTPUT_STREAM (stream), new_contents, strlen (new_contents),
191+ &n_written, NULL, &local_error);
192+ g_assert_no_error (local_error);
193+ g_assert_cmpint (n_written, ==, strlen (new_contents));
194+
195+ g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, &local_error);
196+ g_assert_no_error (local_error);
197+
198+ g_clear_object (&stream);
199+
200+ /* At this point, there should still only be one file: `source`. It should
201+ * now be a regular file. `target` should not exist. */
202+ enumerator = g_file_enumerate_children (tmpdir,
203+ G_FILE_ATTRIBUTE_STANDARD_NAME ","
204+ G_FILE_ATTRIBUTE_STANDARD_TYPE,
205+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &local_error);
206+ g_assert_no_error (local_error);
207+
208+ info = g_file_enumerator_next_file (enumerator, NULL, &local_error);
209+ g_assert_no_error (local_error);
210+ g_assert_nonnull (info);
211+
212+ g_assert_cmpstr (g_file_info_get_name (info), ==, "source");
213+ g_assert_cmpint (g_file_info_get_file_type (info), ==, G_FILE_TYPE_REGULAR);
214+
215+ g_clear_object (&info);
216+
217+ info = g_file_enumerator_next_file (enumerator, NULL, &local_error);
218+ g_assert_no_error (local_error);
219+ g_assert_null (info);
220+
221+ g_file_enumerator_close (enumerator, NULL, &local_error);
222+ g_assert_no_error (local_error);
223+ g_clear_object (&enumerator);
224+
225+ /* Double-check that `target` doesn’t exist */
226+ g_assert_false (g_file_query_exists (target_file, NULL));
227+
228+ /* Check the content of `source`. */
229+ g_file_load_contents (source_file,
230+ NULL,
231+ &contents,
232+ &length,
233+ NULL,
234+ &local_error);
235+ g_assert_no_error (local_error);
236+ g_assert_cmpstr (contents, ==, new_contents);
237+ g_assert_cmpuint (length, ==, strlen (new_contents));
238+ g_free (contents);
239+
240+ /* Tidy up. */
241+ g_file_delete (source_file, NULL, &local_error);
242+ g_assert_no_error (local_error);
243+
244+ g_file_delete (tmpdir, NULL, &local_error);
245+ g_assert_no_error (local_error);
246+
247+ g_clear_object (&target_file);
248+ g_clear_object (&source_file);
249+ g_clear_object (&tmpdir);
250+#else /* if !G_OS_UNIX */
251+ g_test_skip ("Symlink replacement tests can only be run on Unix")
252+#endif
253+}
254+
255 static void
256 on_file_deleted (GObject *object,
257 GAsyncResult *result,
258@@ -1752,6 +1859,7 @@ main (int argc, char *argv[])
259 g_test_add_data_func ("/file/async-create-delete/4096", GINT_TO_POINTER (4096), test_create_delete);
260 g_test_add_func ("/file/replace-load", test_replace_load);
261 g_test_add_func ("/file/replace-cancel", test_replace_cancel);
262+ g_test_add_func ("/file/replace-symlink", test_replace_symlink);
263 g_test_add_func ("/file/async-delete", test_async_delete);
264 #ifdef G_OS_UNIX
265 g_test_add_func ("/file/copy-preserve-mode", test_copy_preserve_mode);
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-5.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-5.patch
new file mode 100644
index 0000000000..2334147f7d
--- /dev/null
+++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2021-28153-5.patch
@@ -0,0 +1,55 @@
1From 6c6439261bc7a8a0627519848a7222b3e1bd4ffe Mon Sep 17 00:00:00 2001
2From: Philip Withnall <pwithnall@endlessos.org>
3Date: Wed, 24 Feb 2021 17:42:24 +0000
4Subject: [PATCH 5/5] glocalfileoutputstream: Add a missing O_CLOEXEC flag to
5 replace()
6
7Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
8
9Upstream-Status: Backport [https://mirrors.ocf.berkeley.edu/ubuntu/pool/main/g/glib2.0/glib2.0_2.64.6-1~ubuntu20.04.3.debian.tar.xz]
10CVE: CVE-2021-28153
11Signed-off-by: Neetika Singh <Neetika.Singh@kpit.com>
12Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
13
14---
15 gio/glocalfileoutputstream.c | 15 ++++++++++++---
16 1 file changed, 12 insertions(+), 3 deletions(-)
17
18--- a/gio/glocalfileoutputstream.c
19+++ b/gio/glocalfileoutputstream.c
20@@ -58,6 +58,12 @@
21 #define O_BINARY 0
22 #endif
23
24+#ifndef O_CLOEXEC
25+#define O_CLOEXEC 0
26+#else
27+#define HAVE_O_CLOEXEC 1
28+#endif
29+
30 struct _GLocalFileOutputStreamPrivate {
31 char *tmp_filename;
32 char *original_filename;
33@@ -1223,7 +1229,7 @@ _g_local_file_output_stream_replace (con
34 sync_on_close = FALSE;
35
36 /* If the file doesn't exist, create it */
37- open_flags = O_CREAT | O_EXCL | O_BINARY;
38+ open_flags = O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC;
39 if (readable)
40 open_flags |= O_RDWR;
41 else
42@@ -1253,8 +1259,11 @@ _g_local_file_output_stream_replace (con
43 set_error_from_open_errno (filename, error);
44 return NULL;
45 }
46-
47-
48+#if !defined(HAVE_O_CLOEXEC) && defined(F_SETFD)
49+ else
50+ fcntl (fd, F_SETFD, FD_CLOEXEC);
51+#endif
52+
53 stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL);
54 stream->priv->fd = fd;
55 stream->priv->sync_on_close = sync_on_close;
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 1a006b9f38..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
@@ -18,6 +18,44 @@ SRC_URI = "${GNOME_MIRROR}/glib/${SHRT_VER}/glib-${PV}.tar.xz \
18 file://0001-gio-tests-resources.c-comment-out-a-build-host-only-.patch \ 18 file://0001-gio-tests-resources.c-comment-out-a-build-host-only-.patch \
19 file://tzdata-update.patch \ 19 file://tzdata-update.patch \
20 file://CVE-2020-35457.patch \ 20 file://CVE-2020-35457.patch \
21 file://CVE-2021-27218.patch \
22 file://CVE-2021-27219-01.patch \
23 file://CVE-2021-27219-02.patch \
24 file://CVE-2021-27219-03.patch \
25 file://CVE-2021-27219-04.patch \
26 file://CVE-2021-27219-05.patch \
27 file://CVE-2021-27219-06.patch \
28 file://CVE-2021-27219-07.patch \
29 file://CVE-2021-27219-08.patch \
30 file://CVE-2021-27219-09.patch \
31 file://CVE-2021-27219-10.patch \
32 file://CVE-2021-27219-11.patch \
33 file://CVE-2021-27219-reg1-1.patch \
34 file://CVE-2021-27219-reg1-2.patch \
35 file://CVE-2021-27219-reg1-4.patch \
36 file://CVE-2021-27219-reg1-5.patch \
37 file://CVE-2021-27219-reg2-1.patch \
38 file://CVE-2021-27219-reg2-2.patch \
39 file://CVE-2021-27219-reg2-3.patch \
40 file://CVE-2021-28153-1.patch \
41 file://CVE-2021-28153-2.patch \
42 file://CVE-2021-28153-3.patch \
43 file://CVE-2021-28153-4.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 \
21 " 59 "
22 60
23SRC_URI_append_class-native = " file://relocate-modules.patch" 61SRC_URI_append_class-native = " file://relocate-modules.patch"
diff --git a/meta/recipes-core/glib-2.0/glib.inc b/meta/recipes-core/glib-2.0/glib.inc
index c3ddf18387..1849a6e05c 100644
--- a/meta/recipes-core/glib-2.0/glib.inc
+++ b/meta/recipes-core/glib-2.0/glib.inc
@@ -4,7 +4,7 @@ HOMEPAGE = "https://developer.gnome.org/glib/"
4 4
5# pcre is under BSD; 5# pcre is under BSD;
6# docs/reference/COPYING is with a 'public domain'-like license! 6# docs/reference/COPYING is with a 'public domain'-like license!
7LICENSE = "LGPLv2.1+ & BSD & PD" 7LICENSE = "LGPLv2.1+ & BSD-3-Clause & PD"
8LIC_FILES_CHKSUM = "file://COPYING;md5=4fbd65380cdd255951079008b364516c \ 8LIC_FILES_CHKSUM = "file://COPYING;md5=4fbd65380cdd255951079008b364516c \
9 file://glib/glib.h;beginline=4;endline=17;md5=b88abb7f3ad09607e71cb9d530155906 \ 9 file://glib/glib.h;beginline=4;endline=17;md5=b88abb7f3ad09607e71cb9d530155906 \
10 file://gmodule/COPYING;md5=4fbd65380cdd255951079008b364516c \ 10 file://gmodule/COPYING;md5=4fbd65380cdd255951079008b364516c \