[v6] Add reallocarray function.

Message ID 20170522202515.19374-1-denniswoelfing@gmx.de
State New, archived
Headers

Commit Message

Dennis Wölfing May 22, 2017, 8:25 p.m. UTC
  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.
See <https://sourceware.org/ml/libc-alpha/2014-05/msg00481.html>.

Tested on i686 and x86_64.

2017-05-22  Dennis Wölfing  <denniswoelfing@gmx.de>
            Rüdiger Sonderfeld  <ruediger@c-plusplus.de>

	* 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.
---
 NEWS                                               |   2 +
 include/stdlib.h                                   |   4 +
 malloc/Makefile                                    |   4 +-
 malloc/Versions                                    |   4 +
 malloc/malloc-internal.h                           |  19 ++++
 malloc/malloc.h                                    |   8 ++
 malloc/reallocarray.c                              |  37 +++++++
 malloc/tst-reallocarray.c                          | 119 +++++++++++++++++++++
 manual/memory.texi                                 |  46 ++++++--
 stdlib/stdlib.h                                    |  11 ++
 sysdeps/unix/sysv/linux/aarch64/libc.abilist       |   2 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist         |   2 +
 sysdeps/unix/sysv/linux/arm/libc.abilist           |   2 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist          |   2 +
 sysdeps/unix/sysv/linux/i386/libc.abilist          |   2 +
 sysdeps/unix/sysv/linux/ia64/libc.abilist          |   2 +
 sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist |   2 +
 sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist   |   2 +
 sysdeps/unix/sysv/linux/microblaze/libc.abilist    |   2 +
 .../unix/sysv/linux/mips/mips32/fpu/libc.abilist   |   2 +
 .../unix/sysv/linux/mips/mips32/nofpu/libc.abilist |   2 +
 .../unix/sysv/linux/mips/mips64/n32/libc.abilist   |   2 +
 .../unix/sysv/linux/mips/mips64/n64/libc.abilist   |   2 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist         |   2 +
 .../sysv/linux/powerpc/powerpc32/fpu/libc.abilist  |   2 +
 .../linux/powerpc/powerpc32/nofpu/libc.abilist     |   2 +
 .../sysv/linux/powerpc/powerpc64/libc-le.abilist   |   2 +
 .../unix/sysv/linux/powerpc/powerpc64/libc.abilist |   2 +
 sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist  |   2 +
 sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist  |   2 +
 sysdeps/unix/sysv/linux/sh/libc.abilist            |   2 +
 sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist |   2 +
 sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist |   2 +
 .../sysv/linux/tile/tilegx/tilegx32/libc.abilist   |   2 +
 .../sysv/linux/tile/tilegx/tilegx64/libc.abilist   |   2 +
 sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist  |   2 +
 sysdeps/unix/sysv/linux/x86_64/64/libc.abilist     |   2 +
 sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist    |   2 +
 38 files changed, 298 insertions(+), 12 deletions(-)
 create mode 100644 malloc/reallocarray.c
 create mode 100644 malloc/tst-reallocarray.c
  

Comments

Dennis Wölfing May 29, 2017, 12:28 p.m. UTC | #1
On 22.05.2017 22:25, Dennis Wölfing wrote:
> 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.
> See <https://sourceware.org/ml/libc-alpha/2014-05/msg00481.html>.
> 
> Tested on i686 and x86_64.
> 
> 2017-05-22  Dennis Wölfing  <denniswoelfing@gmx.de>
>             Rüdiger Sonderfeld  <ruediger@c-plusplus.de>
> 
> 	* 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.

Ping
  
Adhemerval Zanella Netto May 30, 2017, 3:17 p.m. UTC | #2
On 22/05/2017 17:25, Dennis Wölfing wrote:
> 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.
> See <https://sourceware.org/ml/libc-alpha/2014-05/msg00481.html>.
> 
> Tested on i686 and x86_64.
> 
> 2017-05-22  Dennis Wölfing  <denniswoelfing@gmx.de>
>             Rüdiger Sonderfeld  <ruediger@c-plusplus.de>
> 
> 	* 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.

LGTM with some nits below.

> diff --git a/NEWS b/NEWS
> index b4ecd6201d..e70bff01db 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -66,6 +66,8 @@ Version 2.26
>  * The port to Native Client running on ARMv7-A (--host=arm-nacl) has been
>    removed.
>  
> +* The reallocarray function has been added to libc.
> +
>  Security related changes:

I would extend it a bit by describing what reallocarray is intended to
(maybe something as 'It is a realloc replacement with a check for integer
overflow when calculating total allocation size').

> diff --git a/malloc/tst-reallocarray.c b/malloc/tst-reallocarray.c
> new file mode 100644
> index 0000000000..e914e2938b
> --- /dev/null
> +++ b/malloc/tst-reallocarray.c
> @@ -0,0 +1,119 @@
> +/* Test for reallocarray.
> +   Copyright (C) 2014-2017 Free Software Foundation, Inc.

It is a new file, so use 2017 instead.

> +   This file is part of the GNU C Library.
> +
> +   The GNU C 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.
> +
> +   The GNU C 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 the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <errno.h>
> +#include <malloc.h>
> +#include <string.h>
> +#include <support/check.h>
> +
> +static int
> +do_test (void)
> +

Extra line.

> diff --git a/manual/memory.texi b/manual/memory.texi
> index a256ca07b2..fb6b594ef1 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

I think it is worth to add FreeBSD 11.0 also supports it.
  
Zack Weinberg May 30, 2017, 4:17 p.m. UTC | #3
Thumbs up from me, too.  Dennis, do you need someone to commit the
patch for you?

zw
  
Dennis Wölfing May 30, 2017, 8:02 p.m. UTC | #4
On 30.05.2017 18:17, Zack Weinberg wrote:
> Thumbs up from me, too.  Dennis, do you need someone to commit the
> patch for you?

Yes, I don't have commit access. But I will first address the issues
Adhemerval Zanella pointed out and send an updated patch.
  
Dennis Wölfing May 30, 2017, 8:02 p.m. UTC | #5
On 30.05.2017 17:17, Adhemerval Zanella wrote:
>> +@strong{Portability Note:} This function is not part of any standard.  It was
>> +first introduced in OpenBSD 5.6.
>> +@end deftypefun
> 
> I think it is worth to add FreeBSD 11.0 also supports it.

I'm not sure about that. It makes sense to mention OpenBSD because that
is where reallocarray originates from. But FreeBSD is not the only other
OS that implements reallocarray. If we mention FreeBSD do we also
mention NetBSD and any other implementation?
I would prefer to leave that sentence as it is.
  
Florian Weimer May 30, 2017, 8:16 p.m. UTC | #6
On 05/30/2017 10:02 PM, Dennis Wölfing wrote:
> On 30.05.2017 17:17, Adhemerval Zanella wrote:
>>> +@strong{Portability Note:} This function is not part of any standard.  It was
>>> +first introduced in OpenBSD 5.6.
>>> +@end deftypefun
>>
>> I think it is worth to add FreeBSD 11.0 also supports it.
> 
> I'm not sure about that. It makes sense to mention OpenBSD because that
> is where reallocarray originates from. But FreeBSD is not the only other
> OS that implements reallocarray. If we mention FreeBSD do we also
> mention NetBSD and any other implementation?
> I would prefer to leave that sentence as it is.

For what it's worth, I agree with you.

Thanks,
Florian
  
Adhemerval Zanella Netto May 30, 2017, 8:27 p.m. UTC | #7
On 30/05/2017 17:02, Dennis Wölfing wrote:
> On 30.05.2017 17:17, Adhemerval Zanella wrote:
>>> +@strong{Portability Note:} This function is not part of any standard.  It was
>>> +first introduced in OpenBSD 5.6.
>>> +@end deftypefun
>>
>> I think it is worth to add FreeBSD 11.0 also supports it.
> 
> I'm not sure about that. It makes sense to mention OpenBSD because that
> is where reallocarray originates from. But FreeBSD is not the only other
> OS that implements reallocarray. If we mention FreeBSD do we also
> mention NetBSD and any other implementation?
> I would prefer to leave that sentence as it is.

Fair enough.
  
Adhemerval Zanella Netto May 30, 2017, 8:35 p.m. UTC | #8
On 30/05/2017 17:02, Dennis Wölfing wrote:
> On 30.05.2017 18:17, Zack Weinberg wrote:
>> Thumbs up from me, too.  Dennis, do you need someone to commit the
>> patch for you?
> 
> Yes, I don't have commit access. But I will first address the issues
> Adhemerval Zanella pointed out and send an updated patch.
> 

If you have commit access you can just fix the small issues I pointed
out and push upstream (no need to resend a new version).
  
Dennis Wölfing May 30, 2017, 8:39 p.m. UTC | #9
On 30.05.2017 22:35, Adhemerval Zanella wrote:
> On 30/05/2017 17:02, Dennis Wölfing wrote:
>> On 30.05.2017 18:17, Zack Weinberg wrote:
>>> Thumbs up from me, too.  Dennis, do you need someone to commit the
>>> patch for you?
>>
>> Yes, I don't have commit access. But I will first address the issues
>> Adhemerval Zanella pointed out and send an updated patch.
>>
> 
> If you have commit access you can just fix the small issues I pointed
> out and push upstream (no need to resend a new version).
> 

I think you misunderstood me. The "Yes" referred to the question whether
I need someone else to commit it. I don't have commit access.
  
Adhemerval Zanella Netto May 30, 2017, 8:40 p.m. UTC | #10
On 30/05/2017 17:39, Dennis Wölfing wrote:
> On 30.05.2017 22:35, Adhemerval Zanella wrote:
>> On 30/05/2017 17:02, Dennis Wölfing wrote:
>>> On 30.05.2017 18:17, Zack Weinberg wrote:
>>>> Thumbs up from me, too.  Dennis, do you need someone to commit the
>>>> patch for you?
>>>
>>> Yes, I don't have commit access. But I will first address the issues
>>> Adhemerval Zanella pointed out and send an updated patch.
>>>
>>
>> If you have commit access you can just fix the small issues I pointed
>> out and push upstream (no need to resend a new version).
>>
> 
> I think you misunderstood me. The "Yes" referred to the question whether
> I need someone else to commit it. I don't have commit access.
> 

Alright, when you post the new version I can push it upstream for you.
  

Patch

diff --git a/NEWS b/NEWS
index b4ecd6201d..e70bff01db 100644
--- a/NEWS
+++ b/NEWS
@@ -66,6 +66,8 @@  Version 2.26
 * The port to Native Client running on ARMv7-A (--host=arm-nacl) has been
   removed.
 
+* The reallocarray function has been added to libc.
+
 Security related changes:
 
 * The DNS stub resolver limits the advertised UDP buffer size to 1200 bytes,
diff --git a/include/stdlib.h b/include/stdlib.h
index c3ee680bd6..5847445fd3 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -110,6 +110,10 @@  extern int __posix_memalign (void **memptr, size_t alignment, size_t size);
 extern void *__libc_memalign (size_t alignment, size_t size)
      __attribute_malloc__;
 
+extern void *__libc_reallocarray (void *__ptr, size_t __nmemb, size_t __size)
+     __THROW __attribute_warn_unused_result__;
+libc_hidden_proto (__libc_reallocarray)
+
 extern int __libc_system (const char *line);
 
 
diff --git a/malloc/Makefile b/malloc/Makefile
index d0f23f7bf3..b7d4c63920 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -26,7 +26,7 @@  dist-headers := malloc.h
 headers := $(dist-headers) obstack.h mcheck.h
 tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
 	 tst-mcheck tst-mallocfork tst-trim1 \
-	 tst-malloc-usable tst-realloc tst-posix_memalign \
+	 tst-malloc-usable tst-realloc tst-reallocarray tst-posix_memalign \
 	 tst-pvalloc tst-memalign tst-mallopt \
 	 tst-malloc-backtrace tst-malloc-thread-exit \
 	 tst-malloc-thread-fail tst-malloc-fork-deadlock \
@@ -49,7 +49,7 @@  endif
 tests += $(tests-static)
 test-srcs = tst-mtrace
 
-routines = malloc morecore mcheck mtrace obstack \
+routines = malloc morecore mcheck mtrace obstack reallocarray \
   scratch_buffer_grow scratch_buffer_grow_preserve \
   scratch_buffer_set_array_size
 
diff --git a/malloc/Versions b/malloc/Versions
index e34ab177be..23aafb5ccc 100644
--- a/malloc/Versions
+++ b/malloc/Versions
@@ -62,6 +62,7 @@  libc {
     aligned_alloc;
   }
   GLIBC_2.26 {
+    reallocarray;
   }
   GLIBC_PRIVATE {
     # Internal startup hook for libpthread.
@@ -74,5 +75,8 @@  libc {
     __libc_scratch_buffer_grow;
     __libc_scratch_buffer_grow_preserve;
     __libc_scratch_buffer_set_array_size;
+
+    # Internal name for reallocarray
+    __libc_reallocarray;
   }
 }
diff --git a/malloc/malloc-internal.h b/malloc/malloc-internal.h
index de6103d7e1..dbd801a58e 100644
--- a/malloc/malloc-internal.h
+++ b/malloc/malloc-internal.h
@@ -81,5 +81,24 @@  void __malloc_fork_unlock_parent (void) internal_function attribute_hidden;
 /* Called in the child process after a fork.  */
 void __malloc_fork_unlock_child (void) internal_function attribute_hidden;
 
+/* Set *RESULT to LEFT * RIGHT.  Return true if the multiplication
+   overflowed.  */
+static inline bool
+check_mul_overflow_size_t (size_t left, size_t right, size_t *result)
+{
+#if __GNUC__ >= 5
+  return __builtin_mul_overflow (left, right, result);
+#else
+  /* size_t is unsigned so the behavior on overflow is defined.  */
+  *result = left * right;
+  size_t half_size_t = ((size_t) 1) << (8 * sizeof (size_t) / 2);
+  if (__glibc_unlikely ((left | right) >= half_size_t))
+    {
+      if (__glibc_unlikely (right != 0 && *result / right != left))
+        return true;
+    }
+  return false;
+#endif
+}
 
 #endif /* _MALLOC_INTERNAL_H */
diff --git a/malloc/malloc.h b/malloc/malloc.h
index 274c0958e4..339ab64c7d 100644
--- a/malloc/malloc.h
+++ b/malloc/malloc.h
@@ -49,6 +49,14 @@  __THROW __attribute_malloc__ __wur;
 extern void *realloc (void *__ptr, size_t __size)
 __THROW __attribute_warn_unused_result__;
 
+/* Re-allocate the previously allocated block in PTR, making the new
+   block large enough for NMEMB elements of SIZE bytes each.  */
+/* __attribute_malloc__ is not used, because if reallocarray returns
+   the same pointer that was passed to it, aliasing needs to be allowed
+   between objects pointed by the old and new pointers.  */
+extern void *reallocarray (void *__ptr, size_t __nmemb, size_t __size)
+__THROW __attribute_warn_unused_result__;
+
 /* Free a block allocated by `malloc', `realloc' or `calloc'.  */
 extern void free (void *__ptr) __THROW;
 
diff --git a/malloc/reallocarray.c b/malloc/reallocarray.c
new file mode 100644
index 0000000000..07562c30c9
--- /dev/null
+++ b/malloc/reallocarray.c
@@ -0,0 +1,37 @@ 
+/* Change the size of an allocated block.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C 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.
+
+   The GNU C 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 the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <malloc.h>
+#include <malloc/malloc-internal.h>
+
+void *
+__libc_reallocarray (void *optr, size_t nmemb, size_t elem_size)
+{
+  size_t bytes;
+  if (check_mul_overflow_size_t (nmemb, elem_size, &bytes))
+    {
+      __set_errno (ENOMEM);
+      return 0;
+    }
+  else
+    return realloc (optr, bytes);
+}
+libc_hidden_def (__libc_reallocarray)
+
+weak_alias (__libc_reallocarray, reallocarray)
diff --git a/malloc/tst-reallocarray.c b/malloc/tst-reallocarray.c
new file mode 100644
index 0000000000..e914e2938b
--- /dev/null
+++ b/malloc/tst-reallocarray.c
@@ -0,0 +1,119 @@ 
+/* Test for reallocarray.
+   Copyright (C) 2014-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C 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.
+
+   The GNU C 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 the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <malloc.h>
+#include <string.h>
+#include <support/check.h>
+
+static int
+do_test (void)
+
+{
+  void *ptr = NULL;
+  void *ptr2 = NULL;
+  unsigned char *c;
+  size_t i;
+  int ok;
+  const size_t max = ~(size_t)0;
+  size_t a, b;
+
+  /* Test overflow detection.  */
+  errno = 0;
+  ptr = reallocarray (NULL, max, 2);
+  TEST_VERIFY (!ptr);
+  TEST_VERIFY (errno == ENOMEM);
+
+  errno = 0;
+  ptr = reallocarray (NULL, 2, max);
+  TEST_VERIFY (!ptr);
+  TEST_VERIFY (errno == ENOMEM);
+
+  a = 65537;
+  b = max/65537 + 1;
+  errno = 0;
+  ptr = reallocarray (NULL, a, b);
+  TEST_VERIFY (!ptr);
+  TEST_VERIFY (errno == ENOMEM);
+
+  errno = 0;
+  ptr = reallocarray (NULL, b, a);
+  TEST_VERIFY (!ptr);
+  TEST_VERIFY (errno == ENOMEM);
+
+  /* Test realloc-like behavior.  */
+  /* Allocate memory like malloc.  */
+  ptr = reallocarray (NULL, 10, 2);
+  TEST_VERIFY_EXIT (ptr);
+  TEST_VERIFY_EXIT (malloc_usable_size (ptr) >= 10*2);
+
+  memset (ptr, 0xAF, 10*2);
+
+  /* Enlarge buffer.   */
+  ptr2 = reallocarray (ptr, 20, 2);
+  TEST_VERIFY (ptr2);
+  if (ptr2)
+    ptr = ptr2;
+  TEST_VERIFY (malloc_usable_size (ptr) >= 20*2);
+
+  c = ptr;
+  ok = 1;
+  for (i = 0; i < 10*2; ++i)
+    {
+      if (c[i] != 0xAF)
+        ok = 0;
+    }
+  TEST_VERIFY (ok);
+
+  /* Decrease buffer size.  */
+  ptr2 = reallocarray (ptr, 5, 3);
+  TEST_VERIFY (ptr2);
+  if (ptr2)
+    ptr = ptr2;
+  TEST_VERIFY_EXIT (malloc_usable_size (ptr) >= 5*3);
+
+  c = ptr;
+  ok = 1;
+  for (i = 0; i < 5*3; ++i)
+    {
+      if (c[i] != 0xAF)
+        ok = 0;
+    }
+  TEST_VERIFY (ok);
+
+  /* Overflow should leave buffer untouched.  */
+  errno = 0;
+  ptr2 = reallocarray (ptr, 2, ~(size_t)0);
+  TEST_VERIFY (!ptr2);
+  TEST_VERIFY (errno == ENOMEM);
+
+  c = ptr;
+  ok = 1;
+  for (i = 0; i < 5*3; ++i)
+    {
+      if (c[i] != 0xAF)
+        ok = 0;
+    }
+  TEST_VERIFY (ok);
+
+  free (ptr);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/manual/memory.texi b/manual/memory.texi
index a256ca07b2..fb6b594ef1 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
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index 99125f2d23..428ca2ef68 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -422,6 +422,17 @@  extern void *calloc (size_t __nmemb, size_t __size)
    between objects pointed by the old and new pointers.  */
 extern void *realloc (void *__ptr, size_t __size)
      __THROW __attribute_warn_unused_result__;
+
+#ifdef __USE_GNU
+/* Re-allocate the previously allocated block in PTR, making the new
+   block large enough for NMEMB elements of SIZE bytes each.  */
+/* __attribute_malloc__ is not used, because if reallocarray returns
+   the same pointer that was passed to it, aliasing needs to be allowed
+   between objects pointed by the old and new pointers.  */
+extern void *reallocarray (void *__ptr, size_t __nmemb, size_t __size)
+     __THROW __attribute_warn_unused_result__;
+#endif
+
 /* Free a block allocated by `malloc', `realloc' or `calloc'.  */
 extern void free (void *__ptr) __THROW;
 
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 58d768c6bc..a494c3947d 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2097,3 +2097,5 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 906050d2c3..2fc1a9bae7 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2008,6 +2008,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
index 66112dd0a7..4465a62ff1 100644
--- a/sysdeps/unix/sysv/linux/arm/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
@@ -98,6 +98,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.4 GLIBC_2.4 A
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 3ddadd2a24..96126d9e6a 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -1862,6 +1862,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 977ab90bc7..aae351bbff 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2020,6 +2020,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index c7edb9a272..81ec65bec0 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1884,6 +1884,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 450be4e9c1..9db205b68e 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -99,6 +99,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.4 GLIBC_2.4 A
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 9e016bd76e..ee59e950b6 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -1976,6 +1976,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
index 1a455be0f5..feb869757c 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
@@ -2097,3 +2097,5 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 8eb5e668b9..a5b1c42929 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -1951,6 +1951,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 416d9ac0ae..570a859aac 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -1949,6 +1949,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index f4949e5a38..71008ad873 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -1947,6 +1947,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index c7375aee3f..1a07d66caf 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1942,6 +1942,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 724a0e3a04..a62a41be62 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2138,3 +2138,5 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 2dc32b631c..f4f11dc625 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -1980,6 +1980,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 5658109ca2..2977569f2c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -1985,6 +1985,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
index c761221ffe..271d32e19b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2185,3 +2185,5 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index 265c76914b..372ef67c27 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -99,6 +99,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 _Exit F
 GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index ed1b6bf26f..705ff851a9 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -1980,6 +1980,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 2e75d29e47..21fd2b5671 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1881,6 +1881,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
index bd74c0cdab..313a71e589 100644
--- a/sysdeps/unix/sysv/linux/sh/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
@@ -1866,6 +1866,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 5584838409..94a4fb2213 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -1972,6 +1972,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index efedbe2874..6db5811c3f 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1910,6 +1910,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
index ffd988a33d..5d83926aac 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
@@ -2104,3 +2104,5 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
index f0c13ceea8..ce14ceb15f 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
@@ -2104,3 +2104,5 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
index ffd988a33d..5d83926aac 100644
--- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
@@ -2104,3 +2104,5 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index f57004c860..f69de7aa83 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1861,6 +1861,8 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 05629e17e7..a330855308 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2104,3 +2104,5 @@  GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
+GLIBC_2.26 GLIBC_2.26 A
+GLIBC_2.26 reallocarray F