mirror of
git://git.savannah.gnu.org/guix.git
synced 2023-12-14 03:33:07 +01:00
177 lines
5.7 KiB
Diff
177 lines
5.7 KiB
Diff
|
Backport of:
|
|||
|
|
|||
|
From 5e5f75a77e399c638be66d74e5daa8caeb433e00 Mon Sep 17 00:00:00 2001
|
|||
|
From: Philip Withnall <pwithnall@endlessos.org>
|
|||
|
Date: Thu, 4 Feb 2021 13:30:52 +0000
|
|||
|
Subject: [PATCH 01/11] gstrfuncs: Add internal g_memdup2() function
|
|||
|
MIME-Version: 1.0
|
|||
|
Content-Type: text/plain; charset=UTF-8
|
|||
|
Content-Transfer-Encoding: 8bit
|
|||
|
|
|||
|
This will replace the existing `g_memdup()` function for use within
|
|||
|
GLib. It 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.
|
|||
|
|
|||
|
In GLib 2.68, `g_memdup2()` will be a new public API. In this version
|
|||
|
for backport to older stable releases, it’s a new `static inline` API
|
|||
|
in a private header, so that use of `g_memdup()` within GLib can be
|
|||
|
fixed without adding a new API in a stable release series.
|
|||
|
|
|||
|
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
|
|||
|
Helps: GHSL-2021-045
|
|||
|
Helps: #2319
|
|||
|
---
|
|||
|
docs/reference/glib/meson.build | 1 +
|
|||
|
glib/gstrfuncsprivate.h | 55 +++++++++++++++++++++++++++++++++
|
|||
|
glib/meson.build | 1 +
|
|||
|
glib/tests/strfuncs.c | 23 ++++++++++++++
|
|||
|
4 files changed, 80 insertions(+)
|
|||
|
create mode 100644 glib/gstrfuncsprivate.h
|
|||
|
|
|||
|
diff --git a/docs/reference/glib/meson.build b/docs/reference/glib/meson.build
|
|||
|
index bba7649f0..ee39f6d04 100644
|
|||
|
--- a/docs/reference/glib/meson.build
|
|||
|
+++ b/docs/reference/glib/meson.build
|
|||
|
@@ -22,6 +22,7 @@ if get_option('gtk_doc')
|
|||
|
'gprintfint.h',
|
|||
|
'gmirroringtable.h',
|
|||
|
'gscripttable.h',
|
|||
|
+ 'gstrfuncsprivate.h',
|
|||
|
'glib-mirroring-tab',
|
|||
|
'gnulib',
|
|||
|
'pcre',
|
|||
|
diff --git a/glib/gstrfuncsprivate.h b/glib/gstrfuncsprivate.h
|
|||
|
new file mode 100644
|
|||
|
index 000000000..85c88328a
|
|||
|
--- /dev/null
|
|||
|
+++ b/glib/gstrfuncsprivate.h
|
|||
|
@@ -0,0 +1,55 @@
|
|||
|
+/* GLIB - Library of useful routines for C programming
|
|||
|
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
|||
|
+ *
|
|||
|
+ * This library is free software; you can redistribute it and/or
|
|||
|
+ * modify it under the terms of the GNU Lesser General Public
|
|||
|
+ * License as published by the Free Software Foundation; either
|
|||
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|||
|
+ *
|
|||
|
+ * This library is distributed in the hope that it will be useful,
|
|||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|||
|
+ * Lesser General Public License for more details.
|
|||
|
+ *
|
|||
|
+ * You should have received a copy of the GNU Lesser General Public
|
|||
|
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|||
|
+ */
|
|||
|
+
|
|||
|
+#include <glib.h>
|
|||
|
+#include <string.h>
|
|||
|
+
|
|||
|
+/*
|
|||
|
+ * 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.
|
|||
|
+ *
|
|||
|
+ * This static inline version is a backport of the new public API from
|
|||
|
+ * GLib 2.68, kept internal to GLib for backport to older stable releases.
|
|||
|
+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2319.
|
|||
|
+ *
|
|||
|
+ * Returns: (nullable): a pointer to the newly-allocated copy of the memory,
|
|||
|
+ * or %NULL if @mem is %NULL.
|
|||
|
+ * Since: 2.68
|
|||
|
+ */
|
|||
|
+static inline 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;
|
|||
|
+}
|
|||
|
diff --git a/glib/meson.build b/glib/meson.build
|
|||
|
index aaf5f00f5..5a6eea397 100644
|
|||
|
--- a/glib/meson.build
|
|||
|
+++ b/glib/meson.build
|
|||
|
@@ -268,6 +268,7 @@ glib_sources = files(
|
|||
|
'gslist.c',
|
|||
|
'gstdio.c',
|
|||
|
'gstrfuncs.c',
|
|||
|
+ 'gstrfuncsprivate.h',
|
|||
|
'gstring.c',
|
|||
|
'gstringchunk.c',
|
|||
|
'gtestutils.c',
|
|||
|
diff --git a/glib/tests/strfuncs.c b/glib/tests/strfuncs.c
|
|||
|
index e1f9619c7..d968afff9 100644
|
|||
|
--- a/glib/tests/strfuncs.c
|
|||
|
+++ b/glib/tests/strfuncs.c
|
|||
|
@@ -32,6 +32,8 @@
|
|||
|
#include <string.h>
|
|||
|
#include "glib.h"
|
|||
|
|
|||
|
+#include "gstrfuncsprivate.h"
|
|||
|
+
|
|||
|
#if defined (_MSC_VER) && (_MSC_VER <= 1800)
|
|||
|
#define isnan(x) _isnan(x)
|
|||
|
|
|||
|
@@ -219,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)
|
|||
|
@@ -2523,6 +2545,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);
|
|||
|
--
|
|||
|
2.30.1
|
|||
|
|