From feff097f27aa2962c1eed845d3ccebac4cedfcf3 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Thu, 4 Feb 2021 14:15:26 +0000 Subject: [PATCH] gstrfuncs: Deprecate g_memdup() in favour of g_memdup2() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unfortunately, `g_memdup()` accepts its size argument as a `guint`, unlike most other functions which deal with memory sizes — they all use `gsize`. `gsize` is 64 bits on 64-bit machines, while `guint` is only 32 bits. This can lead to a silent (with default compiler warnings) truncation of the value provided by the caller. For large values, this will result in the returned heap allocation being significantly smaller than the caller expects, which will then lead to buffer overflow reads/writes. Any code using `g_memdup()` should immediately port to `g_memdup2()` and check the pointer arithmetic around their call site to ensure there aren’t other overflows. Signed-off-by: Philip Withnall Fixes: #2319 --- glib/gstrfuncs.c | 3 +++ glib/gstrfuncs.h | 6 +++--- glib/tests/strfuncs.c | 4 ++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/glib/gstrfuncs.c b/glib/gstrfuncs.c index 9ee9459e7..b6ff60f51 100644 --- a/glib/gstrfuncs.c +++ b/glib/gstrfuncs.c @@ -380,6 +380,9 @@ g_strdup (const gchar *str) * * Returns: a pointer to the newly-allocated copy of the memory, or %NULL if @mem * is %NULL. + * Deprecated: 2.68: Use g_memdup2() instead, as it accepts a #gsize argument + * for @byte_size, avoiding the possibility of overflow in a #gsize → #guint + * conversion */ gpointer g_memdup (gconstpointer mem, diff --git a/glib/gstrfuncs.h b/glib/gstrfuncs.h index 47cdb0adb..2b44c9a55 100644 --- a/glib/gstrfuncs.h +++ b/glib/gstrfuncs.h @@ -253,9 +253,9 @@ GLIB_AVAILABLE_IN_ALL gchar* g_strescape (const gchar *source, const gchar *exceptions) G_GNUC_MALLOC; -GLIB_AVAILABLE_IN_ALL -gpointer g_memdup (gconstpointer mem, - guint byte_size) G_GNUC_ALLOC_SIZE(2); +GLIB_DEPRECATED_IN_2_68_FOR (g_memdup2) +gpointer g_memdup (gconstpointer mem, + guint byte_size) G_GNUC_ALLOC_SIZE(2); GLIB_AVAILABLE_IN_2_68 gpointer g_memdup2 (gconstpointer mem, diff --git a/glib/tests/strfuncs.c b/glib/tests/strfuncs.c index d6eaee385..ab93f8602 100644 --- a/glib/tests/strfuncs.c +++ b/glib/tests/strfuncs.c @@ -205,6 +205,8 @@ test_is_to_digit (void) static void test_memdup (void) { + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + gchar *str_dup = NULL; const gchar *str = "The quick brown fox jumps over the lazy dog"; @@ -219,6 +221,8 @@ test_memdup (void) g_assert_cmpstr (str, ==, str_dup); g_free (str_dup); + + G_GNUC_END_IGNORE_DEPRECATIONS } /* Testing g_memdup2() function with various positive and negative cases */