This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2] Add getrandom implementation [BZ #17252]


The attached patch does not attempt to make it less likely that the getrandom emulation will fail. The file descriptor is kept open only for the duration of the call. I move the declaration to <sys/random.h> (a new file) and added some documentation.

I kept the protection against symbol interposition. I dropped the getrandom alias because it would lead to compile failures because certain forms of autoconf checks would succeed, but compilation would likely fail because neither <stdlib.h> nor <unistd.h> declare getrandom.

It looks like I have to split all GRND_RANDOM tests into an xtest because on idle build servers, even the few bytes that are currently consumed with GRND_RANDOM cause very long blocking, beyond any reasonable test timeout.

Thanks,
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..f446f8f 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/stat.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 cancelallation 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..138b1f2 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, see
+@ref{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..377fbe2
--- /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
+
+/* 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..c49c89a
--- /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 is 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 spurios bytes\n",
+              length, flags);
+      errors = true;
+    }
+}
+
+/* Call getrandom repeatedly to fille 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..4cea107
--- /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
+     reported 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 missign 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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]