gstrfuncs: Deprecate g_memdup() in favour of g_memdup2()

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 <pwithnall@endlessos.org>
Fixes: #2319
This commit is contained in:
Philip Withnall 2021-02-04 14:15:26 +00:00
parent 20cfc75d14
commit feff097f27
3 changed files with 10 additions and 3 deletions

View File

@ -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,

View File

@ -253,7 +253,7 @@ GLIB_AVAILABLE_IN_ALL
gchar* g_strescape (const gchar *source,
const gchar *exceptions) G_GNUC_MALLOC;
GLIB_AVAILABLE_IN_ALL
GLIB_DEPRECATED_IN_2_68_FOR (g_memdup2)
gpointer g_memdup (gconstpointer mem,
guint byte_size) G_GNUC_ALLOC_SIZE(2);

View File

@ -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 */