mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-14 13:26:16 +01:00
gstrfuncs: Add internal g_memdup2() function
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
This commit is contained in:
parent
79c5866d31
commit
5e5f75a77e
@ -22,6 +22,7 @@ if get_option('gtk_doc')
|
||||
'gprintfint.h',
|
||||
'gmirroringtable.h',
|
||||
'gscripttable.h',
|
||||
'gstrfuncsprivate.h',
|
||||
'gtrace-private.h',
|
||||
'glib-mirroring-tab',
|
||||
'gnulib',
|
||||
|
55
glib/gstrfuncsprivate.h
Normal file
55
glib/gstrfuncsprivate.h
Normal file
@ -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;
|
||||
}
|
@ -284,6 +284,7 @@ glib_sources = files(
|
||||
'gslist.c',
|
||||
'gstdio.c',
|
||||
'gstrfuncs.c',
|
||||
'gstrfuncsprivate.h',
|
||||
'gstring.c',
|
||||
'gstringchunk.c',
|
||||
'gtestutils.c',
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include <string.h>
|
||||
#include "glib.h"
|
||||
|
||||
#include "gstrfuncsprivate.h"
|
||||
|
||||
#if defined (_MSC_VER) && (_MSC_VER <= 1800)
|
||||
#define isnan(x) _isnan(x)
|
||||
|
||||
@ -221,6 +223,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)
|
||||
@ -2541,6 +2563,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