3 From 0736b7c1e7cf4232c5d7eb2b0fbfe9be81bd3baa Mon Sep 17 00:00:00 2001
4 From: Philip Withnall <pwithnall@endlessos.org>
5 Date: Thu, 4 Feb 2021 13:41:21 +0000
6 Subject: [PATCH 04/11] glib: Use g_memdup2() instead of g_memdup() in obvious
9 Content-Type: text/plain; charset=UTF-8
10 Content-Transfer-Encoding: 8bit
12 Convert all the call sites which use `g_memdup()`’s length argument
13 trivially (for example, by passing a `sizeof()` or an existing `gsize`
14 variable), so that they use `g_memdup2()` instead.
16 In almost all of these cases the use of `g_memdup()` would not have
17 caused problems, but it will soon be deprecated, so best port away from
20 In particular, this fixes an overflow within `g_bytes_new()`, identified
21 as GHSL-2021-045 by GHSL team member Kevin Backhouse.
23 Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
27 glib/gbytes.c | 6 ++++--
29 glib/ghash.c | 7 ++++---
30 glib/giochannel.c | 3 ++-
32 glib/gtestutils.c | 3 ++-
33 glib/gvariant.c | 7 ++++---
34 glib/gvarianttype.c | 3 ++-
35 glib/tests/array-test.c | 4 +++-
36 glib/tests/option-context.c | 6 ++++--
37 10 files changed, 29 insertions(+), 16 deletions(-)
39 diff --git a/glib/gbytes.c b/glib/gbytes.c
40 index d56abe6c3..dee494820 100644
47 +#include "gstrfuncsprivate.h"
52 @@ -95,7 +97,7 @@ g_bytes_new (gconstpointer data,
54 g_return_val_if_fail (data != NULL || size == 0, NULL);
56 - return g_bytes_new_take (g_memdup (data, size), size);
57 + return g_bytes_new_take (g_memdup2 (data, size), size);
61 @@ -499,7 +501,7 @@ g_bytes_unref_to_data (GBytes *bytes,
62 * Copy: Non g_malloc (or compatible) allocator, or static memory,
63 * so we have to copy, and then unref.
65 - result = g_memdup (bytes->data, bytes->size);
66 + result = g_memdup2 (bytes->data, bytes->size);
68 g_bytes_unref (bytes);
70 diff --git a/glib/gdir.c b/glib/gdir.c
71 index 6b85e99c8..6747a8c6f 100644
76 #include "gfileutils.h"
77 #include "gstrfuncs.h"
78 +#include "gstrfuncsprivate.h"
79 #include "gtestutils.h"
82 @@ -112,7 +113,7 @@ g_dir_open_with_errno (const gchar *path,
86 - return g_memdup (&dir, sizeof dir);
87 + return g_memdup2 (&dir, sizeof dir);
91 diff --git a/glib/ghash.c b/glib/ghash.c
92 index e61b03788..26f26062b 100644
97 #include "glib-private.h"
98 #include "gstrfuncs.h"
99 +#include "gstrfuncsprivate.h"
101 #include "gtestutils.h"
103 @@ -964,7 +965,7 @@ g_hash_table_ensure_keyval_fits (GHashTable *hash_table, gpointer key, gpointer
104 if (hash_table->have_big_keys)
107 - hash_table->values = g_memdup (hash_table->keys, sizeof (gpointer) * hash_table->size);
108 + hash_table->values = g_memdup2 (hash_table->keys, sizeof (gpointer) * hash_table->size);
109 /* Keys and values are both big now, so no need for further checks */
112 @@ -972,7 +973,7 @@ g_hash_table_ensure_keyval_fits (GHashTable *hash_table, gpointer key, gpointer
116 - hash_table->values = g_memdup (hash_table->keys, sizeof (guint) * hash_table->size);
117 + hash_table->values = g_memdup2 (hash_table->keys, sizeof (guint) * hash_table->size);
121 @@ -1000,7 +1001,7 @@ g_hash_table_ensure_keyval_fits (GHashTable *hash_table, gpointer key, gpointer
123 /* Just split if necessary */
124 if (is_a_set && key != value)
125 - hash_table->values = g_memdup (hash_table->keys, sizeof (gpointer) * hash_table->size);
126 + hash_table->values = g_memdup2 (hash_table->keys, sizeof (gpointer) * hash_table->size);
130 diff --git a/glib/giochannel.c b/glib/giochannel.c
131 index 1956e9dc6..15927c391 100644
132 --- a/glib/giochannel.c
133 +++ b/glib/giochannel.c
135 #include "giochannel.h"
137 #include "gstrfuncs.h"
138 +#include "gstrfuncsprivate.h"
139 #include "gtestutils.h"
140 #include "glibintl.h"
142 @@ -892,7 +893,7 @@ g_io_channel_set_line_term (GIOChannel *channel,
143 length = strlen (line_term);
145 g_free (channel->line_term);
146 - channel->line_term = line_term ? g_memdup (line_term, length) : NULL;
147 + channel->line_term = line_term ? g_memdup2 (line_term, length) : NULL;
148 channel->line_term_len = length;
151 diff --git a/glib/gslice.c b/glib/gslice.c
152 index 4c758c3be..bcdbb8853 100644
157 #include "gmem.h" /* gslice.h */
158 #include "gstrfuncs.h"
159 +#include "gstrfuncsprivate.h"
161 #include "gtrashstack.h"
162 #include "gtestutils.h"
163 @@ -350,7 +351,7 @@ g_slice_get_config_state (GSliceConfig ckey,
164 array[i++] = allocator->contention_counters[address];
165 array[i++] = allocator_get_magazine_threshold (allocator, address);
167 - return g_memdup (array, sizeof (array[0]) * *n_values);
168 + return g_memdup2 (array, sizeof (array[0]) * *n_values);
172 diff --git a/glib/gtestutils.c b/glib/gtestutils.c
173 index dd789482f..5887ecc36 100644
174 --- a/glib/gtestutils.c
175 +++ b/glib/gtestutils.c
177 #include "gpattern.h"
179 #include "gstrfuncs.h"
180 +#include "gstrfuncsprivate.h"
184 @@ -3798,7 +3799,7 @@ g_test_log_extract (GTestLogBuffer *tbuffer)
185 if (p <= tbuffer->data->str + mlength)
187 g_string_erase (tbuffer->data, 0, mlength);
188 - tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup (&msg, sizeof (msg)));
189 + tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup2 (&msg, sizeof (msg)));
193 diff --git a/glib/gvariant.c b/glib/gvariant.c
194 index b61bf7278..d6f68a9ea 100644
195 --- a/glib/gvariant.c
196 +++ b/glib/gvariant.c
201 +#include "gstrfuncsprivate.h"
205 @@ -725,7 +726,7 @@ g_variant_new_variant (GVariant *value)
206 g_variant_ref_sink (value);
208 return g_variant_new_from_children (G_VARIANT_TYPE_VARIANT,
209 - g_memdup (&value, sizeof value),
210 + g_memdup2 (&value, sizeof value),
211 1, g_variant_is_trusted (value));
214 @@ -1229,7 +1230,7 @@ g_variant_new_fixed_array (const GVariantType *element_type,
218 - data = g_memdup (elements, n_elements * element_size);
219 + data = g_memdup2 (elements, n_elements * element_size);
220 value = g_variant_new_from_data (array_type, data,
221 n_elements * element_size,
222 FALSE, g_free, data);
223 @@ -1908,7 +1909,7 @@ g_variant_dup_bytestring (GVariant *value,
227 - return g_memdup (original, size + 1);
228 + return g_memdup2 (original, size + 1);
232 diff --git a/glib/gvarianttype.c b/glib/gvarianttype.c
233 index 1a228f73b..07659ff12 100644
234 --- a/glib/gvarianttype.c
235 +++ b/glib/gvarianttype.c
240 +#include "gstrfuncsprivate.h"
243 * SECTION:gvarianttype
244 @@ -1181,7 +1182,7 @@ g_variant_type_new_tuple (const GVariantType * const *items,
245 g_assert (offset < sizeof buffer);
246 buffer[offset++] = ')';
248 - return (GVariantType *) g_memdup (buffer, offset);
249 + return (GVariantType *) g_memdup2 (buffer, offset);
253 diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c
254 index 3fcf1136a..11982f822 100644
255 --- a/glib/tests/array-test.c
256 +++ b/glib/tests/array-test.c
261 +#include "gstrfuncsprivate.h"
263 /* Test data to be passed to any function which calls g_array_new(), providing
264 * the parameters for that call. Most #GArray tests should be repeated for all
265 * possible values of #ArrayTestData. */
266 @@ -1642,7 +1644,7 @@ byte_array_new_take (void)
270 - data = g_memdup ("woooweeewow", 11);
271 + data = g_memdup2 ("woooweeewow", 11);
272 gbarray = g_byte_array_new_take (data, 11);
273 g_assert (gbarray->data == data);
274 g_assert_cmpuint (gbarray->len, ==, 11);
275 diff --git a/glib/tests/option-context.c b/glib/tests/option-context.c
276 index 149d22353..88d2b80d1 100644
277 --- a/glib/tests/option-context.c
278 +++ b/glib/tests/option-context.c
283 +#include "gstrfuncsprivate.h"
285 static GOptionEntry main_entries[] = {
286 { "main-switch", 0, 0,
287 G_OPTION_ARG_NONE, NULL,
288 @@ -256,7 +258,7 @@ join_stringv (int argc, char **argv)
290 copy_stringv (char **argv, int argc)
292 - return g_memdup (argv, sizeof (char *) * (argc + 1));
293 + return g_memdup2 (argv, sizeof (char *) * (argc + 1));
297 @@ -2323,7 +2325,7 @@ test_group_parse (void)
298 g_option_context_add_group (context, group);
300 argv = split_string ("program --test arg1 -f arg2 --group-test arg3 --frob arg4 -z arg5", &argc);
301 - orig_argv = g_memdup (argv, (argc + 1) * sizeof (char *));
302 + orig_argv = g_memdup2 (argv, (argc + 1) * sizeof (char *));
304 retval = g_option_context_parse (context, &argc, &argv, &error);