From 64bcc1176ecdc07f3fe0379942028d2db202464c Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Thu, 4 Feb 2021 13:41:21 +0000 Subject: [PATCH] glib: Use g_memdup2() instead of g_memdup() in obvious places MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert all the call sites which use `g_memdup()`’s length argument trivially (for example, by passing a `sizeof()` or an existing `gsize` variable), so that they use `g_memdup2()` instead. In almost all of these cases the use of `g_memdup()` would not have caused problems, but it will soon be deprecated, so best port away from it In particular, this fixes an overflow within `g_bytes_new()`, identified as GHSL-2021-045 (aka CVE-2021-27219) by GHSL team member Kevin Backhouse. Adapted for GLib 2.58 by Simon McVittie. Signed-off-by: Philip Withnall Fixes: CVE-2021-27219 Fixes: GHSL-2021-045 Helps: #2319 (cherry picked from commit 0736b7c1e7cf4232c5d7eb2b0fbfe9be81bd3baa) [Backport to 2.58: Omit changes to ghash.c, will be a separate commit] [Backport to 2.58: Omit changes to giochannel.c, not needed in this branch] [Backport to 2.58: Omit changes to uri test, not needed in this branch] Signed-off-by: Simon McVittie --- glib/gbytes.c | 6 ++++-- glib/gdir.c | 3 ++- glib/gslice.c | 3 ++- glib/gtestutils.c | 3 ++- glib/gvariant.c | 7 ++++--- glib/gvarianttype.c | 3 ++- 6 files changed, 16 insertions(+), 9 deletions(-) diff --git a/glib/gbytes.c b/glib/gbytes.c index 3b14a51cd..5141170d7 100644 --- a/glib/gbytes.c +++ b/glib/gbytes.c @@ -33,6 +33,8 @@ #include +#include "gstrfuncsprivate.h" + /** * GBytes: * @@ -94,7 +96,7 @@ g_bytes_new (gconstpointer data, { g_return_val_if_fail (data != NULL || size == 0, NULL); - return g_bytes_new_take (g_memdup (data, size), size); + return g_bytes_new_take (g_memdup2 (data, size), size); } /** @@ -490,7 +492,7 @@ g_bytes_unref_to_data (GBytes *bytes, * Copy: Non g_malloc (or compatible) allocator, or static memory, * so we have to copy, and then unref. */ - result = g_memdup (bytes->data, bytes->size); + result = g_memdup2 (bytes->data, bytes->size); *size = bytes->size; g_bytes_unref (bytes); } diff --git a/glib/gdir.c b/glib/gdir.c index cb4ad0b2f..9d955d57f 100644 --- a/glib/gdir.c +++ b/glib/gdir.c @@ -37,6 +37,7 @@ #include "gconvert.h" #include "gfileutils.h" #include "gstrfuncs.h" +#include "gstrfuncsprivate.h" #include "gtestutils.h" #include "glibintl.h" @@ -113,7 +114,7 @@ g_dir_open_with_errno (const gchar *path, return NULL; #endif - return g_memdup (&dir, sizeof dir); + return g_memdup2 (&dir, sizeof dir); } /** diff --git a/glib/gslice.c b/glib/gslice.c index 454c8a602..8e2359515 100644 --- a/glib/gslice.c +++ b/glib/gslice.c @@ -45,6 +45,7 @@ #include "gmain.h" #include "gmem.h" /* gslice.h */ #include "gstrfuncs.h" +#include "gstrfuncsprivate.h" #include "gutils.h" #include "gtrashstack.h" #include "gtestutils.h" @@ -352,7 +353,7 @@ g_slice_get_config_state (GSliceConfig ckey, array[i++] = allocator->contention_counters[address]; array[i++] = allocator_get_magazine_threshold (allocator, address); *n_values = i; - return g_memdup (array, sizeof (array[0]) * *n_values); + return g_memdup2 (array, sizeof (array[0]) * *n_values); default: return NULL; } diff --git a/glib/gtestutils.c b/glib/gtestutils.c index 0447dcda5..14e071fce 100644 --- a/glib/gtestutils.c +++ b/glib/gtestutils.c @@ -49,6 +49,7 @@ #include "gpattern.h" #include "grand.h" #include "gstrfuncs.h" +#include "gstrfuncsprivate.h" #include "gtimer.h" #include "gslice.h" #include "gspawn.h" @@ -3397,7 +3398,7 @@ g_test_log_extract (GTestLogBuffer *tbuffer) if (p <= tbuffer->data->str + mlength) { g_string_erase (tbuffer->data, 0, mlength); - tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup (&msg, sizeof (msg))); + tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup2 (&msg, sizeof (msg))); return TRUE; } diff --git a/glib/gvariant.c b/glib/gvariant.c index 8be9ce798..45a1a73dc 100644 --- a/glib/gvariant.c +++ b/glib/gvariant.c @@ -33,6 +33,7 @@ #include +#include "gstrfuncsprivate.h" /** * SECTION:gvariant @@ -720,7 +721,7 @@ g_variant_new_variant (GVariant *value) g_variant_ref_sink (value); return g_variant_new_from_children (G_VARIANT_TYPE_VARIANT, - g_memdup (&value, sizeof value), + g_memdup2 (&value, sizeof value), 1, g_variant_is_trusted (value)); } @@ -1224,7 +1225,7 @@ g_variant_new_fixed_array (const GVariantType *element_type, return NULL; } - data = g_memdup (elements, n_elements * element_size); + data = g_memdup2 (elements, n_elements * element_size); value = g_variant_new_from_data (array_type, data, n_elements * element_size, FALSE, g_free, data); @@ -1901,7 +1902,7 @@ g_variant_dup_bytestring (GVariant *value, if (length) *length = size; - return g_memdup (original, size + 1); + return g_memdup2 (original, size + 1); } /** diff --git a/glib/gvarianttype.c b/glib/gvarianttype.c index 9910dee93..7de4202cb 100644 --- a/glib/gvarianttype.c +++ b/glib/gvarianttype.c @@ -27,6 +27,7 @@ #include +#include "gstrfuncsprivate.h" /** * SECTION:gvarianttype @@ -1109,7 +1110,7 @@ g_variant_type_new_tuple (const GVariantType * const *items, g_assert (offset < sizeof buffer); buffer[offset++] = ')'; - return (GVariantType *) g_memdup (buffer, offset); + return (GVariantType *) g_memdup2 (buffer, offset); } /**