From: Bruno Haible Date: Mon, 21 Oct 2024 13:29:40 +0000 (+0200) Subject: realloc: Optionally check for undefined behaviour. X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=12cd6eca2058105f81c3a5dc739e82f965ca18bf;p=gnulib.git realloc: Optionally check for undefined behaviour. * m4/realloc.m4 (gl_FUNC_REALLOC_SANITIZED): New macro. (gl_FUNC_REALLOC_POSIX): Require it. If a sanitized realloc is requested, define NEED_SANITIZED_REALLOC and compile realloc.c. (gl_FUNC_REALLOC_GNU): Require it. If a sanitized realloc is requested, don't compile realloc.c a second time. * lib/realloc.c (rpl_realloc): If NEED_SANITIZED_REALLOC is defined, abort in the case of undefined behaviour. --- diff --git a/ChangeLog b/ChangeLog index 0b7094e650..4e5e61b654 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2024-10-21 Bruno Haible + + realloc: Optionally check for undefined behaviour. + * m4/realloc.m4 (gl_FUNC_REALLOC_SANITIZED): New macro. + (gl_FUNC_REALLOC_POSIX): Require it. If a sanitized realloc is + requested, define NEED_SANITIZED_REALLOC and compile realloc.c. + (gl_FUNC_REALLOC_GNU): Require it. If a sanitized realloc is requested, + don't compile realloc.c a second time. + * lib/realloc.c (rpl_realloc): If NEED_SANITIZED_REALLOC is defined, + abort in the case of undefined behaviour. + 2024-10-19 Paul Eggert realloc: more improvements for realloc (p, 0) diff --git a/lib/realloc.c b/lib/realloc.c index 0573139625..5cfe3bc747 100644 --- a/lib/realloc.c +++ b/lib/realloc.c @@ -42,8 +42,19 @@ rpl_realloc (void *p, size_t n) if (n == 0) { +#if NEED_SANITIZED_REALLOC + /* ISO C 23 § 7.24.3.7.(3) says that this case is undefined behaviour. + Let the programmer know that it occurred. + When the undefined-behaviour sanitizers report this case, i.e. when + and + + have been closed and new releases of GCC and clang have been made, + we can remove this code here. */ + abort (); +#else free (p); return NULL; +#endif } if (xalloc_oversized (n, 1)) diff --git a/m4/realloc.m4 b/m4/realloc.m4 index e25f329c50..f4d78f9622 100644 --- a/m4/realloc.m4 +++ b/m4/realloc.m4 @@ -1,11 +1,23 @@ # realloc.m4 -# serial 32 +# serial 33 dnl Copyright (C) 2007, 2009-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl This file is offered as-is, without any warranty. +# An an experimental option, the user can request a sanitized realloc() +# implementation, i.e. one that aborts upon undefined behaviour, +# by setting +# gl_cv_func_realloc_sanitize=yes +# at configure time. +AC_DEFUN([gl_FUNC_REALLOC_SANITIZED], +[ + AC_CACHE_CHECK([whether realloc should abort upon undefined behaviour], + [gl_cv_func_realloc_sanitize], + [test -n "$gl_cv_func_realloc_sanitize" || gl_cv_func_realloc_sanitize=no]) +]) + # This is adapted with modifications from upstream Autoconf here: # https://git.savannah.gnu.org/cgit/autoconf.git/tree/lib/autoconf/functions.m4?id=v2.70#n1455 AC_DEFUN([_AC_FUNC_REALLOC_IF], @@ -51,7 +63,9 @@ AC_DEFUN([gl_FUNC_REALLOC_GNU], dnl gets defined already before this macro gets invoked. This helps dnl if !(__VEC__ || __AIXVEC), and doesn't hurt otherwise. - if test $REPLACE_REALLOC_FOR_REALLOC_GNU = 0; then + AC_REQUIRE([gl_FUNC_REALLOC_SANITIZED]) + if test "$gl_cv_func_realloc_sanitize" = no \ + && test $REPLACE_REALLOC_FOR_REALLOC_GNU = 0; then _AC_FUNC_REALLOC_IF([], [REPLACE_REALLOC_FOR_REALLOC_GNU=1]) fi ])# gl_FUNC_REALLOC_GNU @@ -65,7 +79,14 @@ AC_DEFUN([gl_FUNC_REALLOC_POSIX], [ AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) AC_REQUIRE([gl_FUNC_MALLOC_POSIX]) - if test $REPLACE_MALLOC_FOR_MALLOC_POSIX = 1; then + AC_REQUIRE([gl_FUNC_REALLOC_SANITIZED]) + if test "$gl_cv_func_realloc_sanitize" != no; then REPLACE_REALLOC_FOR_REALLOC_POSIX=1 + AC_DEFINE([NEED_SANITIZED_REALLOC], [1], + [Define to 1 if realloc should abort upon undefined behaviour.]) + else + if test $REPLACE_MALLOC_FOR_MALLOC_POSIX = 1; then + REPLACE_REALLOC_FOR_REALLOC_POSIX=1 + fi fi ])