mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
gstrfuncs: Add g_memdup2() function
This will replace the existing `g_memdup()` function, which has an unavoidable security flaw of taking its `byte_size` argument as a `guint` rather than as a `gsize`. Most callers will expect it to be a `gsize`, and may pass in large values which could silently be truncated, resulting in an undersize allocation compared to what the caller expects. This could lead to a classic buffer overflow vulnerability for many callers of `g_memdup()`. `g_memdup2()`, in comparison, takes its `byte_size` as a `gsize`. Spotted by Kevin Backhouse of GHSL. Signed-off-by: Philip Withnall <pwithnall@endlessos.org> Helps: GHSL-2021-045 Helps: #2319
This commit is contained in:
parent
8385664f47
commit
f8cf0b8672
@ -1341,6 +1341,7 @@ g_newa
|
||||
<SUBSECTION>
|
||||
g_memmove
|
||||
g_memdup
|
||||
g_memdup2
|
||||
|
||||
<SUBSECTION>
|
||||
GMemVTable
|
||||
|
@ -398,6 +398,38 @@ g_memdup (gconstpointer mem,
|
||||
return new_mem;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_memdup2:
|
||||
* @mem: (nullable): the memory to copy.
|
||||
* @byte_size: the number of bytes to copy.
|
||||
*
|
||||
* Allocates @byte_size bytes of memory, and copies @byte_size bytes into it
|
||||
* from @mem. If @mem is %NULL it returns %NULL.
|
||||
*
|
||||
* This replaces g_memdup(), which was prone to integer overflows when
|
||||
* converting the argument from a #gsize to a #guint.
|
||||
*
|
||||
* Returns: (nullable): a pointer to the newly-allocated copy of the memory,
|
||||
* or %NULL if @mem is %NULL.
|
||||
* Since: 2.68
|
||||
*/
|
||||
gpointer
|
||||
g_memdup2 (gconstpointer mem,
|
||||
gsize byte_size)
|
||||
{
|
||||
gpointer new_mem;
|
||||
|
||||
if (mem && byte_size != 0)
|
||||
{
|
||||
new_mem = g_malloc (byte_size);
|
||||
memcpy (new_mem, mem, byte_size);
|
||||
}
|
||||
else
|
||||
new_mem = NULL;
|
||||
|
||||
return new_mem;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_strndup:
|
||||
* @str: the string to duplicate
|
||||
|
@ -257,6 +257,10 @@ GLIB_AVAILABLE_IN_ALL
|
||||
gpointer g_memdup (gconstpointer mem,
|
||||
guint byte_size) G_GNUC_ALLOC_SIZE(2);
|
||||
|
||||
GLIB_AVAILABLE_IN_2_68
|
||||
gpointer g_memdup2 (gconstpointer mem,
|
||||
gsize byte_size) G_GNUC_ALLOC_SIZE(2);
|
||||
|
||||
/* NULL terminated string arrays.
|
||||
* g_strsplit(), g_strsplit_set() split up string into max_tokens tokens
|
||||
* at delim and return a newly allocated string array.
|
||||
|
@ -221,6 +221,26 @@ test_memdup (void)
|
||||
g_free (str_dup);
|
||||
}
|
||||
|
||||
/* Testing g_memdup2() function with various positive and negative cases */
|
||||
static void
|
||||
test_memdup2 (void)
|
||||
{
|
||||
gchar *str_dup = NULL;
|
||||
const gchar *str = "The quick brown fox jumps over the lazy dog";
|
||||
|
||||
/* Testing negative cases */
|
||||
g_assert_null (g_memdup2 (NULL, 1024));
|
||||
g_assert_null (g_memdup2 (str, 0));
|
||||
g_assert_null (g_memdup2 (NULL, 0));
|
||||
|
||||
/* Testing normal usage cases */
|
||||
str_dup = g_memdup2 (str, strlen (str) + 1);
|
||||
g_assert_nonnull (str_dup);
|
||||
g_assert_cmpstr (str, ==, str_dup);
|
||||
|
||||
g_free (str_dup);
|
||||
}
|
||||
|
||||
/* Testing g_strpcpy() function with various positive and negative cases */
|
||||
static void
|
||||
test_stpcpy (void)
|
||||
@ -2539,6 +2559,7 @@ main (int argc,
|
||||
g_test_add_func ("/strfuncs/has-prefix", test_has_prefix);
|
||||
g_test_add_func ("/strfuncs/has-suffix", test_has_suffix);
|
||||
g_test_add_func ("/strfuncs/memdup", test_memdup);
|
||||
g_test_add_func ("/strfuncs/memdup2", test_memdup2);
|
||||
g_test_add_func ("/strfuncs/stpcpy", test_stpcpy);
|
||||
g_test_add_func ("/strfuncs/str_match_string", test_str_match_string);
|
||||
g_test_add_func ("/strfuncs/str_tokenize_and_fold", test_str_tokenize_and_fold);
|
||||
|
Loading…
Reference in New Issue
Block a user