diff options
author | Darshit Shah <darnir@gnu.org> | 2017-08-13 10:13:33 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2017-08-13 11:02:40 -0700 |
commit | 98756762a3337722477d2cddc9c0549609efe848 (patch) | |
tree | 4f2c711b6df8dc8eb98f894d589246af4cf667b1 | |
parent | 0474f8e6a85621c276dfc47099b9863a47f96a0d (diff) | |
download | gnulib-98756762a3337722477d2cddc9c0549609efe848.tar.gz |
reallocarray: New module
reallocarray is a new function in glibc 2.26 to safely allocate an array
of memory locations with integer overflow protection.
* MODULES.html.sh: Add reallocarray.
* doc/glibc-functions/reallocarray.texi: Documentation for reallocarray.
* lib/reallocarray.c: New file to implement module reallocarray.
* lib/stdlib.in.h: Add function declarations for reallocarray.
* m4/reallocarray.m4: New file.
* m4/stdlib_h.m4: Declare reallocarray.
* modules/reallocarray: New file.
* modules/reallocarray-test: New file.
* modules/stdlib: Coerce stdlib.h to export reallocarray.
* tests/test-reallocarray.c: New test.
-rw-r--r-- | ChangeLog | 16 | ||||
-rwxr-xr-x | MODULES.html.sh | 1 | ||||
-rw-r--r-- | doc/glibc-functions/reallocarray.texi | 22 | ||||
-rw-r--r-- | lib/reallocarray.c | 37 | ||||
-rw-r--r-- | lib/stdlib.in.h | 17 | ||||
-rw-r--r-- | m4/reallocarray.m4 | 20 | ||||
-rw-r--r-- | m4/stdlib_h.m4 | 8 | ||||
-rw-r--r-- | modules/reallocarray | 32 | ||||
-rw-r--r-- | modules/reallocarray-tests | 11 | ||||
-rw-r--r-- | modules/stdlib | 2 | ||||
-rw-r--r-- | tests/test-reallocarray.c | 41 |
11 files changed, 204 insertions, 3 deletions
@@ -1,3 +1,19 @@ +2017-08-13 Darshit Shah <darnir@gnu.org> + + reallocarray: New module + reallocarray is a new function in glibc 2.26 to safely allocate an array + of memory locations with integer overflow protection. + * MODULES.html.sh: Add reallocarray. + * doc/glibc-functions/reallocarray.texi: Documentation for reallocarray. + * lib/reallocarray.c: New file to implement module reallocarray. + * lib/stdlib.in.h: Add function declarations for reallocarray. + * m4/reallocarray.m4: New file. + * m4/stdlib_h.m4: Declare reallocarray. + * modules/reallocarray: New file. + * modules/reallocarray-test: New file. + * modules/stdlib: Coerce stdlib.h to export reallocarray. + * tests/test-reallocarray.c: New test. + 2017-08-12 Paul Eggert <eggert@cs.ucla.edu> dirent-safer: fix cloexec race diff --git a/MODULES.html.sh b/MODULES.html.sh index a64b9997e0..1a258b632e 100755 --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -1703,6 +1703,7 @@ func_all_modules () func_module free func_module malloc-gnu func_module realloc-gnu + func_module reallocarray func_module pagealign_alloc func_end_table diff --git a/doc/glibc-functions/reallocarray.texi b/doc/glibc-functions/reallocarray.texi new file mode 100644 index 0000000000..6ce4a9397a --- /dev/null +++ b/doc/glibc-functions/reallocarray.texi @@ -0,0 +1,22 @@ +@node reallocarray +@subsection @code{reallocarray} +@findex reallocarray + +Gnulib module: reallocarray + +Allocate multiple memory locations of a fixed size with integer overflow +protection. +Glibc Manual: @url{https://www.gnu.org/software/libc/manual/html_node/Changing-Block-Size.html#Changing-Block-Size} + +Portability problems fixed by Gnulib: +@itemize +@item +This function is missing on many platforms: +glibc 2.25, macOS 10.13, FreeBSD 11.0, NetBSD 7.1, OpenBSD 5.5, Minix 3.1.8, +AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11 2011-11, Cygwin, mingw, +MSVC 14, Interix 3.5, BeOS. +@end itemize + +Portability problems not fixed by Gnulib: +@itemize +@end itemize diff --git a/lib/reallocarray.c b/lib/reallocarray.c new file mode 100644 index 0000000000..05357a4432 --- /dev/null +++ b/lib/reallocarray.c @@ -0,0 +1,37 @@ +/* reallocarray() function that is glibc compatible. + + Copyright (C) 2017 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* written by Darshit Shah */ + +#include <config.h> + +#include <stdlib.h> +#include <errno.h> + +#include "xalloc-oversized.h" + +void * +reallocarray(void *ptr, size_t nmemb, size_t size) +{ + if (xalloc_oversized (nmemb, size)) + { + errno = ENOMEM; + return NULL; + } + /* We rely on using the semantics of the GNU realloc() function here. */ + return realloc(ptr, nmemb * size); +} diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index b5cf9d3695..c6e68fddc4 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -765,6 +765,23 @@ _GL_WARN_ON_USE (realloc, "realloc is not POSIX compliant everywhere - " "use gnulib module realloc-posix for portability"); #endif + +#if @GNULIB_REALLOCARRAY@ +# if ! @HAVE_REALLOCARRAY@ +_GL_FUNCDECL_SYS (reallocarray, void *, + (void *ptr, size_t nmemb, size_t size)); +# endif +_GL_CXXALIAS_SYS (reallocarray, void *, + (void *ptr, size_t nmemb, size_t size)); +_GL_CXXALIASWARN (reallocarray); +#elif defined GNULIB_POSIXCHECK +# undef reallocarray +# if HAVE_RAW_DECL_REALLOCARRAY +_GL_WARN_ON_USE (reallocarray, "reallocarray is not portable - " + "use gnulib module reallocarray for portability"); +# endif +#endif + #if @GNULIB_REALPATH@ # if @REPLACE_REALPATH@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) diff --git a/m4/reallocarray.m4 b/m4/reallocarray.m4 new file mode 100644 index 0000000000..261df7a907 --- /dev/null +++ b/m4/reallocarray.m4 @@ -0,0 +1,20 @@ +# reallocarray.m4 serial 1 +dnl Copyright (C) 2017 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. + +AC_DEFUN([gl_FUNC_REALLOCARRAY], +[ + dnl Persuade glibc <stdlib.h> to declare reallocarray(). + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_CHECK_FUNCS([reallocarray]) + if test $ac_cv_func_reallocarray = no; then + HAVE_REALLOCARRAY=0 + fi +]) + +# Prerequisites of lib/reallocarray.c. +AC_DEFUN([gl_PREREQ_REALLOCARRAY], [:]) diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4 index 110fe2d1a9..ec4a058154 100644 --- a/m4/stdlib_h.m4 +++ b/m4/stdlib_h.m4 @@ -21,9 +21,9 @@ AC_DEFUN([gl_STDLIB_H], #endif ]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt initstate initstate_r mkdtemp mkostemp mkostemps mkstemp mkstemps - posix_openpt ptsname ptsname_r qsort_r random random_r realpath rpmatch - secure_getenv setenv setstate setstate_r srandom srandom_r - strtod strtoll strtoull unlockpt unsetenv]) + posix_openpt ptsname ptsname_r qsort_r random random_r reallocarray + realpath rpmatch secure_getenv setenv setstate setstate_r srandom + srandom_r strtod strtoll strtoull unlockpt unsetenv]) ]) AC_DEFUN([gl_STDLIB_MODULE_INDICATOR], @@ -58,6 +58,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], GNULIB_QSORT_R=0; AC_SUBST([GNULIB_QSORT_R]) GNULIB_RANDOM=0; AC_SUBST([GNULIB_RANDOM]) GNULIB_RANDOM_R=0; AC_SUBST([GNULIB_RANDOM_R]) + GNULIB_REALLOCARRAY=0; AC_SUBST([GNULIB_REALLOCARRAY]) GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX]) GNULIB_REALPATH=0; AC_SUBST([GNULIB_REALPATH]) GNULIB_RPMATCH=0; AC_SUBST([GNULIB_RPMATCH]) @@ -89,6 +90,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS], HAVE_RANDOM=1; AC_SUBST([HAVE_RANDOM]) HAVE_RANDOM_H=1; AC_SUBST([HAVE_RANDOM_H]) HAVE_RANDOM_R=1; AC_SUBST([HAVE_RANDOM_R]) + HAVE_REALLOCARRAY=1; AC_SUBST([HAVE_REALLOCARRAY]) HAVE_REALPATH=1; AC_SUBST([HAVE_REALPATH]) HAVE_RPMATCH=1; AC_SUBST([HAVE_RPMATCH]) HAVE_SECURE_GETENV=1; AC_SUBST([HAVE_SECURE_GETENV]) diff --git a/modules/reallocarray b/modules/reallocarray new file mode 100644 index 0000000000..f833d46dc1 --- /dev/null +++ b/modules/reallocarray @@ -0,0 +1,32 @@ +Description: +reallocarray() function that is glibc compatible. + +Files: +lib/reallocarray.c +m4/reallocarray.m4 + +Depends-on: +extensions +xalloc-oversized +realloc-gnu +stdlib + +configure.ac: +gl_FUNC_REALLOCARRAY +if test $HAVE_REALLOCARRAY = 0; then + AC_LIBOBJ([reallocarray]) + gl_PREREQ_REALLOCARRAY +fi +gl_MODULE_INDICATOR([reallocarray]) +gl_STDLIB_MODULE_INDICATOR([reallocarray]) + +Makefile.am: + +Include: +<stdlib.h> + +License: +GPLv3+ + +Maintainer: +all diff --git a/modules/reallocarray-tests b/modules/reallocarray-tests new file mode 100644 index 0000000000..3943d7295b --- /dev/null +++ b/modules/reallocarray-tests @@ -0,0 +1,11 @@ +Files: +tests/test-reallocarray.c +tests/signature.h + +Depends-on: + +configure.ac: + +Makefile.am: +TESTS += test-reallocarray +check_PROGRAMS += test-reallocarray diff --git a/modules/stdlib b/modules/stdlib index 27b1caa3bb..257b5dbd69 100644 --- a/modules/stdlib +++ b/modules/stdlib @@ -53,6 +53,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \ -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \ -e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \ + -e 's/@''GNULIB_REALLOCARRAY''@/$(GNULIB_REALLOCARRAY)/g' \ -e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \ -e 's/@''GNULIB_RPMATCH''@/$(GNULIB_RPMATCH)/g' \ -e 's/@''GNULIB_SECURE_GETENV''@/$(GNULIB_SECURE_GETENV)/g' \ @@ -83,6 +84,7 @@ stdlib.h: stdlib.in.h $(top_builddir)/config.status $(CXXDEFS_H) \ -e 's|@''HAVE_RANDOM''@|$(HAVE_RANDOM)|g' \ -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \ -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \ + -e 's|@''HAVE_REALLOCARRAY''@|$(HAVE_REALLOCARRAY)|g' \ -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \ -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \ -e 's|@''HAVE_SECURE_GETENV''@|$(HAVE_SECURE_GETENV)|g' \ diff --git a/tests/test-reallocarray.c b/tests/test-reallocarray.c new file mode 100644 index 0000000000..587c700015 --- /dev/null +++ b/tests/test-reallocarray.c @@ -0,0 +1,41 @@ +/* Test of reallocarray function. + Copyright (C) 2010-2017 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include <stdlib.h> +#include <errno.h> + +#include "signature.h" +SIGNATURE_CHECK (reallocarray, void *, (void *, size_t, size_t)); + +int +main () +{ + size_t n; + /* Check that reallocarray fails when requested to allocate a block of memory + larger than SIZE_MAX bytes. */ + for (n = 2; n != 0; n <<= 1) + { + if (reallocarray (NULL, (size_t) -1 / n + 1, n)) + return 1; + + /* Ensure that errno is correctly set */ + if (!errno == ENOMEM) + return 1; + } + return 0; +} |