[glib: 1/12] gstrfuncs: Add g_memdup2() function
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 1/12] gstrfuncs: Add g_memdup2() function
- Date: Thu, 4 Feb 2021 17:12:37 +0000 (UTC)
commit f8cf0b8672209e0b829542e194e302f1de169929
Author: Philip Withnall <pwithnall endlessos org>
Date: Thu Feb 4 13:30:52 2021 +0000
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
docs/reference/glib/glib-sections.txt | 1 +
glib/gstrfuncs.c | 32 ++++++++++++++++++++++++++++++++
glib/gstrfuncs.h | 4 ++++
glib/tests/strfuncs.c | 21 +++++++++++++++++++++
4 files changed, 58 insertions(+)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index d0121801a..2e219cf0c 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -1341,6 +1341,7 @@ g_newa
<SUBSECTION>
g_memmove
g_memdup
+g_memdup2
<SUBSECTION>
GMemVTable
diff --git a/glib/gstrfuncs.c b/glib/gstrfuncs.c
index afedf4f78..9ee9459e7 100644
--- a/glib/gstrfuncs.c
+++ b/glib/gstrfuncs.c
@@ -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
diff --git a/glib/gstrfuncs.h b/glib/gstrfuncs.h
index fc88cc1c5..47cdb0adb 100644
--- a/glib/gstrfuncs.h
+++ b/glib/gstrfuncs.h
@@ -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.
diff --git a/glib/tests/strfuncs.c b/glib/tests/strfuncs.c
index 37cbc5a8a..d6eaee385 100644
--- a/glib/tests/strfuncs.c
+++ b/glib/tests/strfuncs.c
@@ -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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]