This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH v2] Add getrandom implementation [BZ #17252]
- From: Florian Weimer <fweimer at redhat dot com>
- To: Rical Jasan <ricaljasan at pacific dot net>
- Cc: libc-alpha <libc-alpha at sourceware dot org>
- Date: Thu, 8 Sep 2016 11:53:12 +0200
- Subject: Re: [PATCH v2] Add getrandom implementation [BZ #17252]
- Authentication-results: sourceware.org; auth=none
- References: <88371300-c533-9886-f1de-e34f17f7cbb4@redhat.com> <5774E713.5000907@pacific.net>
On 06/30/2016 11:32 AM, Rical Jasan wrote:
> +#ifndef _SYS_RANDOM_H
> +#define _SYS_RANDOM_H
Isn't there a preferred way of doing this that defines _SYS_RANDOM_H to
1? I seem to remember a wiki page that talked about protecting against
typos.
This might defeat the header guard optimization. Existing practice
varies, some headers use 1, some don't.
> How strict is the coding style about unnecessary parentheses?
I prefer adding braces to if statements if they are nested and some have
else branches.
> Really though, reading the code, it made sense to me.
Thanks. I'm attaching a version with your comments (not rebased to 2.25
though). We may need this code again if we ever implement a
arc4random-style interface.
(I think the consensus for getrandom is to add only a thin wrapper
around the system call, if we are going to add it at all.)
Florian
Add getrandom implementation [BZ #17252]
The emulation opens /dev/random and /dev/urandom (depending
on the flags), reads random bytes, and closes the descriptor
again.
The getrandom function is defined as a macro in such a way that
a direct attempt to define a getrandom function will either
fail to compile, or fail to interpose the __getrandom symbol.
The intent is that legacy implementations will not accidentally
preempt the implementation in gzlibc (which could well be used
by other libraries in the same process image).
2016-06-27 Florian Weimer <fweimer@redhat.com>
[BZ #17252]
* stdlib/sys/random.h: New file.
(headers): Add it.
* stdlib/Makefile (routines): Add getrandom.
(tests): Add tst-getrandom.
* stdlib/Versions (GLIBC_2.24): Add __getrandom.
* stdlib/getrandom.c: New file.
* stdlib/tst-getrandom.c: Likewise.
* sysdep/posix/getrandom.c: Likewise.
* sysdep/posix/getrandom_emulation.c: Likewise.
* sysdeps/unix/sysv/linux/getrandom.c: Likewise.
* sysdeps/unix/sysv/linux/kernel-features.h
(__ASSUME_GETRANDOM_SYSCALL): Define.
* manual/crypt.texi (Unpredictable Bytes): New section.
* manual/math.texi (Pseudo-Random Numbers): Add cross-reference.
* sysdeps/arm/nacl/libc.abilist: Add __getrandom.
* sysdeps/unix/sysv/linux/aarch64/libc.abilist: Likewise.
* 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/tile/tilepro/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise.
diff --git a/NEWS b/NEWS
index e2737d5..c6b32de 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,10 @@ Version 2.24
unchanged). Linux 3.2 or later kernel headers are required on all
architectures.
+* The getrandom function and the <sys/random.h> header file have been added.
+ This function will use the Linux getrandom system call to obtain random
+ data if available.
+
* The pap_AN locale has been deleted. This has been deprecated for a long
time. It has been replaced by pap_AW & pap_CW, both of which have long
been included in previous releases.
diff --git a/manual/crypt.texi b/manual/crypt.texi
index 659688b..082ad70 100644
--- a/manual/crypt.texi
+++ b/manual/crypt.texi
@@ -45,6 +45,7 @@ encrypted authentication use normal DES.
* getpass:: Prompting the user for a password.
* crypt:: A one-way function for passwords.
* DES Encryption:: Routines for DES encryption.
+* Unpredictable Bytes:: Randomness for cryptography purposes.
@end menu
@node Legal Problems
@@ -428,3 +429,83 @@ each byte.
The @code{ecb_crypt}, @code{cbc_crypt}, and @code{des_setparity}
functions and their accompanying macros are all defined in the header
@file{rpc/des_crypt.h}.
+
+@node Unpredictable Bytes
+@section Generating Unpredictable Bytes
+
+Some cryptographic applications (such as session key generation) need
+unpredictable bytes.
+
+@comment sys/random.h
+@comment GNU
+@deftypefun ssize_t getrandom (void *@var{buffer}, size_t @var{length}, unsigned int @var{flags})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+
+This function writes @var{length} bytes of random data to the array
+starting at @var{buffer}. On succes, this function returns the number
+of bytes which have been written to the buffer (which can be less than
+@var{length}). On error, @code{-1} is returned, and @code{errno} is
+updated accordingly.
+
+The @code{getrandom} function is declared in the header file
+@file{sys/random.h}. It is a GNU extension.
+
+The following flags are defined for the @var{flags} argument:
+
+@table @code
+@item GRND_RANDOM
+Use the blocking pool instead of the non-blocking pool to obtain
+randomness. By default, the non-blocking pool is used. The blocking
+pool corresponds to @file{/dev/random}, and the non-blocking pool to
+@file{/dev/urandom}.
+
+@item GRND_NONBLOCK
+Instead of blocking, return to the caller immediately if no data is
+available.
+@end table
+
+Even access to the non-blocking pool can block if the system has just
+booted and the pool has not yet been initialized.
+
+If the @var{flags} argument is zero, the @code{getrandom} implementation
+in @theglibc{} will only return once @var{length} bytes have been
+written to @var{buffer}, or there is an error (except @code{EINTR}), and
+such a function call is not a cancellation point.
+
+@strong{Note:} If the system lacks support for the @code{getrandom}
+system call, the @code{getrandom} function uses emulation based on the
+@file{/dev/random} and @file{/dev/urandom} device nodes. This results
+in additional failure scenarios, listed below as ``emulation only''.
+
+The @code{getrandom} function can fail with several errors, some of
+which are listed below. In addition, if @var{flags} is not zero, the
+function may not fill the buffer completely and return a value less than
+@var{length}.
+
+@table @code
+@item EAGAIN
+No random data was available and @code{GRND_NONBLOCK} was specified in
+@var{flags}.
+
+@item EFAULT
+The the combination of @var{buffer} and @var{length} arguments specifies
+an invalid memory range.
+
+@item EINTR
+The system call was interrupted (only if flags is not zero).
+
+@item EINVAL
+The @var{flags} argument contains an invalid combination of flags.
+
+@item ENOENT
+@itemx EACCES
+The current file system namespace lacks the required device node, or the
+device node is inaccessible (emulation only).
+
+@item EMFILE
+@itemx ENFILE
+The random device node could not be opened due to process or system
+limits (emulation only).
+@end table
+
+@end deftypefun
diff --git a/manual/math.texi b/manual/math.texi
index 5c9f7b9..917d598 100644
--- a/manual/math.texi
+++ b/manual/math.texi
@@ -1413,7 +1413,8 @@ is convenient when you are debugging a program, but it is unhelpful if
you want the program to behave unpredictably. If you want a different
pseudo-random series each time your program runs, you must specify a
different seed each time. For ordinary purposes, basing the seed on the
-current time works well.
+current time works well. For random numbers in cryptography,
+@pxref{Unpredictable Bytes}.
You can obtain repeatable sequences of numbers on a particular machine type
by specifying the same initial seed value for the random number
diff --git a/stdlib/Makefile b/stdlib/Makefile
index fc6f23d..9055993 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -28,7 +28,7 @@ headers := stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h \
errno.h sys/errno.h bits/errno.h \
ucontext.h sys/ucontext.h \
alloca.h fmtmsg.h \
- bits/stdlib-bsearch.h
+ bits/stdlib-bsearch.h sys/random.h
routines := \
atof atoi atol atoll \
@@ -45,7 +45,7 @@ routines := \
srand48 seed48 lcong48 \
drand48_r erand48_r lrand48_r nrand48_r mrand48_r jrand48_r \
srand48_r seed48_r lcong48_r \
- drand48-iter \
+ drand48-iter getrandom \
strtol strtoul strtoll strtoull \
strtol_l strtoul_l strtoll_l strtoull_l \
strtof strtod strtold \
@@ -77,7 +77,7 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
tst-tininess tst-strtod-underflow tst-tls-atexit \
tst-setcontext3 tst-tls-atexit-nodelete \
tst-strtol-locale tst-strtod-nan-locale tst-strfmon_l \
- tst-quick_exit tst-thread-quick_exit
+ tst-quick_exit tst-thread-quick_exit tst-getrandom
tests-static := tst-secure-getenv
ifeq ($(have-cxx-thread_local),yes)
CFLAGS-tst-quick_exit.o = -std=c++11
diff --git a/stdlib/Versions b/stdlib/Versions
index 9c06b43..8d79f46 100644
--- a/stdlib/Versions
+++ b/stdlib/Versions
@@ -111,6 +111,7 @@ libc {
}
GLIBC_2.24 {
quick_exit;
+ __getrandom;
}
GLIBC_PRIVATE {
# functions which have an additional interface since they are
diff --git a/stdlib/getrandom.c b/stdlib/getrandom.c
new file mode 100644
index 0000000..f0b3181
--- /dev/null
+++ b/stdlib/getrandom.c
@@ -0,0 +1,31 @@
+/* Stub for getrandom.
+ Copyright (C) 2016 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 <sys/random.h>
+
+/* Write LENGTH bytes of randomness starting at BUFFER. Returns the
+ number of bytes written, or -1 on error. */
+ssize_t
+__getrandom (void *buffer, size_t length, unsigned int flags)
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+
+stub_warning (__getrandom)
diff --git a/stdlib/sys/random.h b/stdlib/sys/random.h
new file mode 100644
index 0000000..912807c
--- /dev/null
+++ b/stdlib/sys/random.h
@@ -0,0 +1,35 @@
+/* Interfaces for obtaining random bytes.
+ Copyright (C) 2016 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/>. */
+
+#ifndef _SYS_RANDOM_H
+#define _SYS_RANDOM_H 1
+
+/* Flags for use with getrandom. */
+# define GRND_NONBLOCK 1
+# define GRND_RANDOM 2
+
+/* Write LENGTH bytes of randomness starting at BUFFER. Returns the
+ number of bytes written, or -1 on error. */
+ssize_t __getrandom (void *__buffer, size_t __length, unsigned int __flags)
+ __THROW __wur;
+
+/* Prevent accidental interposition of the getrandom symbol. */
+#define getrandom(buffer, length, flags) \
+ (0 + __getrandom (buffer, length, flags))
+
+#endif /* _SYS_RANDOM_H */
diff --git a/stdlib/tst-getrandom.c b/stdlib/tst-getrandom.c
new file mode 100644
index 0000000..2e4f7e7
--- /dev/null
+++ b/stdlib/tst-getrandom.c
@@ -0,0 +1,162 @@
+/* Tests for the getrandom function.
+ Copyright (C) 2016 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 <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/random.h>
+
+/* Set to true if any errors are encountered. */
+static bool errors;
+
+/* Test getrandom with a single buffer length. */
+static void
+test_length (char *buffer, int length, unsigned flags)
+{
+ memset (buffer, 0, length);
+ strcpy (buffer + length, "123");
+ ssize_t ret = getrandom (buffer, length, flags);
+ if (ret < 0)
+ {
+ if (!((flags & GRND_RANDOM)
+ && (flags & GRND_NONBLOCK)
+ && errno != EAGAIN))
+ {
+ printf ("error: getrandom (%d, 0x%x): %m\n", length, flags);
+ errors = true;
+ }
+ }
+ if (ret != length)
+ {
+ if (flags & GRND_RANDOM)
+ {
+ if (ret == 0 || ret > length)
+ {
+ printf ("error: getrandom (%d, 0x%x) returned %zd\n",
+ length, flags, ret);
+ errors = true;
+ }
+ }
+ else
+ {
+ printf ("error: getrandom (%d, 0x%x) returned %zd\n",
+ length, flags, ret);
+ errors = true;
+ }
+ }
+ if (length >= 7)
+ {
+ /* One spurious test failure in 2**56 is sufficiently
+ unlikely. */
+ int non_null = 0;
+ for (int i = 0; i < length; ++i)
+ non_null += buffer[i] != 0;
+ if (non_null == 0)
+ {
+ printf ("error: getrandom (%d, 0x%x) returned all-zero bytes\n",
+ length, flags);
+ errors = true;
+ }
+ }
+ if (memcmp (buffer + length, "123", 4) != 0)
+ {
+ printf ("error: getrandom (%d, 0x%x) wrote spurious bytes\n",
+ length, flags);
+ errors = true;
+ }
+}
+
+/* Call getrandom repeatedly to fill the buffer. */
+static bool
+getrandom_full (char *buffer, int length, unsigned flags)
+{
+ char *end = buffer + length;
+ while (buffer < end)
+ {
+ ssize_t ret = getrandom (buffer, end - buffer, flags);
+ if (ret < 0)
+ {
+ printf ("error: getrandom (%d, 0x%x): %m\n", length, flags);
+ errors = true;
+ return false;
+ }
+ buffer += ret;
+ }
+
+ return true;
+}
+
+static void
+test_flags (unsigned flags)
+{
+ /* Test various lengths, but only for !GRND_RANDOM, to conserve
+ entropy. */
+ {
+ enum { max_length = 300 };
+ char buffer[max_length + 4];
+ if (flags & GRND_RANDOM)
+ test_length (buffer, 0, flags);
+ else
+ {
+ for (int length = 0; length <= 9; ++length)
+ test_length (buffer, length, flags);
+ test_length (buffer, 16, flags);
+ test_length (buffer, max_length, flags);
+ }
+ }
+
+ /* Test that getrandom returns different data. */
+ if (!(flags & GRND_NONBLOCK))
+ {
+ char buffer1[8];
+ memset (buffer1, 0, sizeof (buffer1));
+
+ char buffer2[8];
+ memset (buffer2, 0, sizeof (buffer2));
+
+ if (getrandom_full (buffer1, sizeof (buffer1), flags)
+ && getrandom_full (buffer1, sizeof (buffer1), flags))
+ {
+ if (memcmp (buffer1, buffer2, sizeof (buffer1)) == 0)
+ {
+ printf ("error: getrandom returns constant value\n");
+ errors = true;
+ }
+ }
+ }
+}
+
+static int
+do_test (void)
+{
+ for (int use_random = 0; use_random < 2; ++use_random)
+ for (int use_nonblock = 0; use_nonblock < 2; ++use_nonblock)
+ {
+ int flags = 0;
+ if (use_random)
+ flags |= GRND_RANDOM;
+ if (use_nonblock)
+ flags |= GRND_NONBLOCK;
+ test_flags (flags);
+ }
+ return errors;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/sysdeps/arm/nacl/libc.abilist b/sysdeps/arm/nacl/libc.abilist
index 2f7751d..b8fb2d5 100644
--- a/sysdeps/arm/nacl/libc.abilist
+++ b/sysdeps/arm/nacl/libc.abilist
@@ -1840,4 +1840,5 @@ GLIBC_2.23 fts64_close F
GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
diff --git a/sysdeps/posix/getrandom.c b/sysdeps/posix/getrandom.c
new file mode 100644
index 0000000..030d8cb
--- /dev/null
+++ b/sysdeps/posix/getrandom.c
@@ -0,0 +1,27 @@
+/* Generic version of getrandom, based on emulation.
+ Copyright (C) 2016 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 "getrandom_emulation.c"
+
+/* Write LENGTH bytes of randomness starting at BUFFER. Returns the
+ number of bytes written, or -1 on error. */
+ssize_t
+__getrandom (void *buffer, size_t length, unsigned int flags)
+{
+ return getrandom_emulation (buffer, length, flags);
+}
diff --git a/sysdeps/posix/getrandom_emulation.c b/sysdeps/posix/getrandom_emulation.c
new file mode 100644
index 0000000..75534d9
--- /dev/null
+++ b/sysdeps/posix/getrandom_emulation.c
@@ -0,0 +1,111 @@
+/* Emulation of the getrandom system call.
+ Copyright (C) 2016 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 <atomic.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libc-lock.h>
+#include <not-cancel.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/* Support flags by this emulation. Additional flags will cause the
+ emulation to fail with EINVAL. */
+#define GETRANDOM_SUPPORTED_FLAGS (GRND_RANDOM | GRND_NONBLOCK)
+
+/* Open the device node for the random device requested by FLAGS.
+ Return -1 on error (and set errno), and the file descriptor on
+ success. */
+static int
+getrandom_open_fd (int flags)
+{
+ int open_flags = O_RDONLY | O_CLOEXEC;
+ if (flags & GRND_NONBLOCK)
+ open_flags |= O_NONBLOCK;
+ const char *device;
+ if (flags & GRND_RANDOM)
+ device = "/dev/random";
+ else
+ device = "/dev/urandom";
+ return open_not_cancel (device, open_flags, 0);
+}
+
+/* Attempt to read LENGTH bytes from FD, avoiding short reads.
+ Intended for getrandom calls without any flags. */
+static ssize_t
+getrandom_read_fd (int fd, void *buffer, size_t length)
+{
+ void *end = buffer + length;
+ while (buffer < end)
+ {
+ /* EINTR can occur without any flags during early userspace
+ initialization. */
+ ssize_t ret = TEMP_FAILURE_RETRY
+ (read_not_cancel (fd, buffer, end - buffer));
+ if (ret < 0)
+ /* Do not report the short read, return the error. */
+ return -1;
+ if (ret == 0)
+ __libc_fatal ("error: end of file on randomness device\n");
+ buffer += ret;
+ }
+ return length;
+}
+
+static void
+getrandom_close_fd (void *pfd)
+{
+ close_not_cancel_no_status (*(int *) pfd);
+}
+
+/* Write LENGTH bytes of randomness starting at BUFFER. Returns the
+ number of bytes written, or -1 on error. Implementation based on
+ emulation with /dev/urandom and /dev/random. */
+static ssize_t
+getrandom_emulation (void *buffer, size_t length, unsigned int flags)
+{
+ /* Check if any unsupported flags have been requested. */
+ if (flags & ~GETRANDOM_SUPPORTED_FLAGS)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ int fd = getrandom_open_fd (flags);
+ if (fd < 0)
+ return -1;
+
+ /* If flags is zero, avoid short reads. */
+ if (flags == 0)
+ {
+ ssize_t ret = getrandom_read_fd (fd, buffer, length);
+ close_not_cancel_no_status (fd);
+ return ret;
+ }
+ else
+ {
+ /* Some flags are set. Allow cancellation, and pass short reads
+ to the caller. */
+ ssize_t ret;
+ __libc_cleanup_push (getrandom_close_fd, &fd);
+ ret = __read (fd, buffer, length);
+ __libc_cleanup_pop (1);
+ return ret;
+ }
+}
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 9cdb623..c27bd60 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2088,4 +2088,5 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index f3f3c70..663ae98 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -1999,6 +1999,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
index a93803d..2db0919 100644
--- a/sysdeps/unix/sysv/linux/arm/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
@@ -89,6 +89,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.4 GLIBC_2.4 A
GLIBC_2.4 _Exit F
diff --git a/sysdeps/unix/sysv/linux/getrandom.c b/sysdeps/unix/sysv/linux/getrandom.c
new file mode 100644
index 0000000..bab2774
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/getrandom.c
@@ -0,0 +1,164 @@
+/* Linux version of getrandom.
+ Copyright (C) 2016 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 <assert.h>
+#include <errno.h>
+#include <kernel-features.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/random.h>
+#include <sysdep-cancel.h>
+#include <unistd.h>
+
+#ifdef __NR_getrandom
+
+/* getrandom system call wrapper with no flags, and which can only
+ process INT_MAX bytes at a time, and retries on EINTR. */
+static int
+getrandom_syscall_intmax (void *buffer, size_t length)
+{
+ return TEMP_FAILURE_RETRY (INLINE_SYSCALL (getrandom, 3, buffer, length, 0));
+}
+
+/* getrandom system call wrapper with no flags, and which can process
+ all lengths and retries on EINTR. */
+static ssize_t
+getrandom_syscall_no_flags (void *buffer, size_t length)
+{
+ void *p = buffer;
+ void *end = buffer + length;
+
+ /* Execute the system call even for length == 0, so that we properly
+ report ENOSYS. Otherwise, the detection of system call
+ availability will not work. */
+ do
+ {
+ size_t to_get = end - p;
+ /* The system call returns an int, so it cannot process more
+ than INT_MAX bytes at a time. */
+ if (to_get > INT_MAX)
+ to_get = INT_MAX;
+ int getrandom_result = getrandom_syscall_intmax (p, to_get);
+ /* Stop on error. Do not report the short read, return the
+ error. */
+ if (getrandom_result < 0)
+ return -1;
+ /* If the system call returns 0 for some reason, we would enter
+ an infinite loop. */
+ assert (getrandom_result > 0 || length == 0);
+ p += getrandom_result;
+ }
+ while (p < end);
+
+ return length;
+}
+
+/* getrandom system call wrapper with special support for FLAGS == 0
+ (EINTR retry, arbitrary lengths). */
+static ssize_t
+getrandom_try_syscall (void *buffer, size_t length, unsigned int flags)
+{
+ if (flags == 0)
+ return getrandom_syscall_no_flags (buffer, length);
+ else
+ return SYSCALL_CANCEL (getrandom, buffer, length, flags);
+}
+
+/* Same as getrandom_try_syscall, but terminate the process on an
+ ENOSYS error. */
+static ssize_t
+getrandom_force_syscall (void *buffer, size_t length, unsigned int flags)
+{
+ ssize_t ret = getrandom_try_syscall (buffer, length, flags);
+ if (ret < 0 && ret == ENOSYS)
+ __libc_fatal ("error: getrandom system call failed with ENONSYS\n");
+ return ret;
+}
+
+# ifdef __ASSUME_GETRANDOM_SYSCALL
+/* Write LENGTH bytes of randomness starting at BUFFER. Returns the
+ number of bytes written, or -1 on error. This implementation uses
+ the system call unconditionally and terminates the process if it
+ fails with ENOSYS. */
+ssize_t
+__getrandom (void *buffer, size_t length, unsigned int flags)
+{
+ return getrandom_force_syscall (buffer, length, flags);
+}
+
+# else /* !__ASSUME_GETRANDOM_SYSCALL */
+# include "getrandom_emulation.c"
+
+/* Possible values: 0: not initialized, 1: system call present,
+ 2: system call missing. */
+static int have_getrandom;
+
+/* Write LENGTH bytes of randomness starting at BUFFER. Returns the
+ number of bytes written, or -1 on error. This implementation falls
+ back to emulation in case the system call is unavailable. */
+ssize_t
+__getrandom (void *buffer, size_t length, unsigned int flags)
+{
+ /* Relaxed MO means that we may issue some additional failing system
+ calls because concurrent calls to __getrandom are not
+ synchronized, but optimizing for repeated calls is more
+ important. */
+ switch (atomic_load_relaxed (&have_getrandom))
+ {
+ case 0:
+ /* Not yet initialized. */
+ {
+ ssize_t ret = getrandom_try_syscall (buffer, length, flags);
+ if (ret < 0 && errno == ENOSYS)
+ {
+ /* Record that the system call is missing and fall back to
+ emulation. */
+ atomic_store_relaxed (&have_getrandom, 2);
+ return getrandom_emulation (buffer, length, flags);
+ }
+ atomic_store_relaxed (&have_getrandom, 1);
+ return ret;
+ }
+ case 1:
+ /* System call is available. */
+ return getrandom_force_syscall (buffer, length, flags);
+ case 2:
+ /* System call is missing. */
+ return getrandom_emulation (buffer, length, flags);
+ }
+ abort ();
+}
+# endif /* __ASSUME_GETRANDOM_SYSCALL */
+
+#else /* !__NR_getrandom */
+
+/* The kernel headers do not mention the getrandom system call. We
+ can only perform emulation. */
+
+# include "getrandom_emulation.c"
+
+/* Write LENGTH bytes of randomness starting at BUFFER. Returns the
+ number of bytes written, or -1 on error. This implementation uses
+ emulation with device nodes. */
+ssize_t
+__getrandom (void *buffer, size_t length, unsigned int flags)
+{
+ return getrandom_emulation (buffer, length, flags);
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 58ed133..45a8628 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -1853,6 +1853,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 61cbae0..8235533 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2011,6 +2011,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index d40d264..44b7967 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1875,6 +1875,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index 1d3b554..4ea4932 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -147,3 +147,8 @@
separate syscalls were only added later. */
#define __ASSUME_SENDMSG_SYSCALL 1
#define __ASSUME_RECVMSG_SYSCALL 1
+
+/* getrandom was added on many architectures in Linux 3.17. */
+#if __LINUX_KERNEL_VERSION >= 0x031100
+# define __ASSUME_GETRANDOM_SYSCALL
+#endif
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 64432ae..c0da3e1 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -90,6 +90,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.4 GLIBC_2.4 A
GLIBC_2.4 _Exit F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 8086c38..8d78844 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -1967,6 +1967,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
index 8c4c3bb..8d0a372 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
@@ -2088,4 +2088,5 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index db014ed..a0c9720 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -1942,6 +1942,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_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 33ac881..4654bcd 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -1940,6 +1940,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_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 b8b2c0e..5dd97e5 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -1938,6 +1938,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_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 0741301..80b39d7 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1933,6 +1933,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index fa04825..f40e205 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2129,4 +2129,5 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 3d633c0..107d834 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -1971,6 +1971,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_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 a6b164b..e23bba9 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -1976,6 +1976,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_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 7200b76..e938823 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2176,4 +2176,5 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index de62ecb..155dc21 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -90,6 +90,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 _Exit F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 8da0bc0..ce8ba8d 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -1971,6 +1971,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_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 59066a9..54d3f0a 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1872,6 +1872,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
index 01ca9e6..05134a3 100644
--- a/sysdeps/unix/sysv/linux/sh/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
@@ -1857,6 +1857,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 245c1c6..ab4bd74 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -1963,6 +1963,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 4478d13..6da3de4 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1901,6 +1901,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_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 c1a2613..7b6bf09 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
@@ -2095,4 +2095,5 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
index 35fbf8a..b9901f8 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
@@ -2095,4 +2095,5 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
index c1a2613..7b6bf09 100644
--- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
@@ -2095,4 +2095,5 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index c1054ce..1ef10d5 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1852,6 +1852,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_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 2fd6d60..ddeb9d2 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2095,4 +2095,5 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
+GLIBC_2.24 __getrandom F
GLIBC_2.24 quick_exit F