From 2e0bbbfbf95fc9e22692e93658a6fbdd2d4554da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20W=C3=B6lfing?= Date: Tue, 30 May 2017 18:26:19 -0300 Subject: Add reallocarray function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reallocarray function is an extension from OpenBSD. It is an integer-overflow-safe replacement for realloc(p, X*Y) and malloc(X*Y) (realloc(NULL, X*Y)). It can therefore help in preventing certain security issues in code. This is an updated version of a patch originally submitted by Rüdiger Sonderfeld in May 2014 [1]. Checked on i686-linux-gnu and x86_64-linux-gnu. [1] . 2017-05-30 Dennis Wölfing Rüdiger Sonderfeld * include/stdlib.h (__libc_reallocarray): New declaration. * malloc/Makefile (routines): Add reallocarray. (tests): Add tst-reallocarray.c. * malloc/Versions: Add reallocarray and __libc_reallocarray. * malloc/malloc-internal.h (check_mul_overflow_size_t): New inline function. * malloc/malloc.h (reallocarray): New declaration. * stdlib/stdlib.h (reallocarray): Likewise. * malloc/reallocarray.c: New file. * malloc/tst-reallocarray.c: New test file. * manual/memory.texi: Document reallocarray. * sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add reallocarray. * sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/arm/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/hppa/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/i386/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/microblaze/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/nios2/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sh/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/tilepro/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise. --- manual/memory.texi | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) (limited to 'manual/memory.texi') diff --git a/manual/memory.texi b/manual/memory.texi index a256ca0..fb6b594 100644 --- a/manual/memory.texi +++ b/manual/memory.texi @@ -751,8 +751,8 @@ be a buffer that you use to hold a line being read from a file; no matter how long you make the buffer initially, you may encounter a line that is longer. -You can make the block longer by calling @code{realloc}. This function -is declared in @file{stdlib.h}. +You can make the block longer by calling @code{realloc} or +@code{reallocarray}. These functions are declared in @file{stdlib.h}. @pindex stdlib.h @comment malloc.h stdlib.h @@ -816,9 +816,29 @@ behavior, and will probably crash when @code{realloc} is passed a null pointer. @end deftypefun -Like @code{malloc}, @code{realloc} may return a null pointer if no -memory space is available to make the block bigger. When this happens, -the original block is untouched; it has not been modified or relocated. +@comment malloc.h stdlib.h +@comment BSD +@deftypefun {void *} reallocarray (void *@var{ptr}, size_t @var{nmemb}, size_t @var{size}) +@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} + +The @code{reallocarray} function changes the size of the block whose address +is @var{ptr} to be long enough to contain a vector of @var{nmemb} elements, +each of size @var{size}. It is equivalent to @samp{realloc (@var{ptr}, +@var{nmemb} * @var{size})}, except that @code{reallocarray} fails safely if +the multiplication overflows, by setting @code{errno} to @code{ENOMEM}, +returning a null pointer, and leaving the original block unchanged. + +@code{reallocarray} should be used instead of @code{realloc} when the new size +of the allocated block is the result of a multiplication that might overflow. + +@strong{Portability Note:} This function is not part of any standard. It was +first introduced in OpenBSD 5.6. +@end deftypefun + +Like @code{malloc}, @code{realloc} and @code{reallocarray} may return a null +pointer if no memory space is available to make the block bigger. When this +happens, the original block is untouched; it has not been modified or +relocated. In most cases it makes no difference what happens to the original block when @code{realloc} fails, because the application program cannot continue @@ -838,16 +858,17 @@ xrealloc (void *ptr, size_t size) @} @end smallexample -You can also use @code{realloc} to make a block smaller. The reason you -would do this is to avoid tying up a lot of memory space when only a little -is needed. +You can also use @code{realloc} or @code{reallocarray} to make a block +smaller. The reason you would do this is to avoid tying up a lot of memory +space when only a little is needed. @comment The following is no longer true with the new malloc. @comment But it seems wise to keep the warning for other implementations. In several allocation implementations, making a block smaller sometimes necessitates copying it, so it can fail if no other space is available. -If the new size you specify is the same as the old size, @code{realloc} -is guaranteed to change nothing and return the same address that you gave. +If the new size you specify is the same as the old size, @code{realloc} and +@code{reallocarray} are guaranteed to change nothing and return the same +address that you gave. @node Allocating Cleared Space @subsubsection Allocating Cleared Space @@ -1588,6 +1609,11 @@ Malloc}. Make a block previously allocated by @code{malloc} larger or smaller, possibly by copying it to a new location. @xref{Changing Block Size}. +@item void *reallocarray (void *@var{ptr}, size_t @var{nmemb}, size_t @var{size}) +Change the size of a block previously allocated by @code{malloc} to +@code{@var{nmemb} * @var{size}} bytes as with @code{realloc}. @xref{Changing +Block Size}. + @item void *calloc (size_t @var{count}, size_t @var{eltsize}) Allocate a block of @var{count} * @var{eltsize} bytes using @code{malloc}, and set its contents to zero. @xref{Allocating Cleared -- cgit v1.1