diff mbox

[v7] getrandom system call wrapper [BZ #17252]

Message ID 3dd5d3b8-c196-98fb-1671-90cd90ab90c7@redhat.com
State New
Headers show

Commit Message

Florian Weimer Nov. 14, 2016, 5:44 p.m. UTC
This patch switches back to the ssize_t return time.  This goes against 
Theodore Ts'o preference, but seems to reflect the consensus from the 
largery community.

I weakened the protection against accidental interposition somewhat. 
Since the declaration is a new header file, I do not use a function-like 
macro to prevent a definition of a function named “getrandom”, and 
non-GNU compilers do not get any redirection.  The rationale is that if 
you interpose the function after including <sys/random.h>, you probably 
know what you are doing.  The redirect to __libc_getrandom still 
provides interposition protection if other translation units define a 
getrandom function without knowledge of <sys/random.h>.

Thanks,
Florian

Comments

Zack Weinberg Nov. 14, 2016, 6:29 p.m. UTC | #1
On 11/14/2016 12:44 PM, Florian Weimer wrote:
> This patch switches back to the ssize_t return time.  This goes against

> Theodore Ts'o preference, but seems to reflect the consensus from the

> largery community.


I still don't think this function should be a cancellation point.

> I weakened the protection against accidental interposition somewhat.

> Since the declaration is a new header file, I do not use a function-like

> macro to prevent a definition of a function named “getrandom”, and

> non-GNU compilers do not get any redirection.


We don't normally do this at all.  I don't understand why this function
should be treated differently.  Can you please explain what concrete
situations, involving real, existing code, you're trying to defend
against here?

zw
Richard Henderson Nov. 15, 2016, 8:57 p.m. UTC | #2
On 11/14/2016 07:29 PM, Zack Weinberg wrote:
> On 11/14/2016 12:44 PM, Florian Weimer wrote:

>> I weakened the protection against accidental interposition somewhat.

>> Since the declaration is a new header file, I do not use a function-like

>> macro to prevent a definition of a function named “getrandom”, and

>> non-GNU compilers do not get any redirection.

>

> We don't normally do this at all.  I don't understand why this function

> should be treated differently.  Can you please explain what concrete

> situations, involving real, existing code, you're trying to defend

> against here?


It has been proposed that we do this for all new non-standardized symbols.

Which does make sense from a certain point of view.  As far as I can see it 
can't hurt, and can only help when it comes to inter-operating with user 
binaries that could have legitimately used the symbols until now.


r~
Florian Weimer Nov. 16, 2016, 3:11 p.m. UTC | #3
On 11/14/2016 07:29 PM, Zack Weinberg wrote:
> On 11/14/2016 12:44 PM, Florian Weimer wrote:

>> This patch switches back to the ssize_t return time.  This goes against

>> Theodore Ts'o preference, but seems to reflect the consensus from the

>> largery community.

>

> I still don't think this function should be a cancellation point.


I guess we'll have to agree to disagree on this matter.

>> I weakened the protection against accidental interposition somewhat.

>> Since the declaration is a new header file, I do not use a function-like

>> macro to prevent a definition of a function named “getrandom”, and

>> non-GNU compilers do not get any redirection.

>

> We don't normally do this at all.


See the “Evolution of ELF symbol management” thread.  We do it all the 
time, for the benefit of non-libc DSOs in the glibc conglomerate.  I 
think there is broad consensus that we need to extend this to libstdc++ 
at least (in addition to changes needed to enable C++ compilation 
without _GNU_SOURCE).  And once we are at C++, why stop there?  Even 
dynamic languages with a C extension framework would use this.

Thanks,
Florian
Zack Weinberg Nov. 16, 2016, 3:20 p.m. UTC | #4
On 11/16/2016 10:11 AM, Florian Weimer wrote:
> On 11/14/2016 07:29 PM, Zack Weinberg wrote:

>> On 11/14/2016 12:44 PM, Florian Weimer wrote:

>>> This patch switches back to the ssize_t return time.  This goes against

>>> Theodore Ts'o preference, but seems to reflect the consensus from the

>>> largery community.

>>

>> I still don't think this function should be a cancellation point.

> 

> I guess we'll have to agree to disagree on this matter.


I am seriously considering escalating my disagreement here to a formal
objection.  I would like to know why you think it is NECESSARY - not
merely convenient or consistent with other stuff - for this function to
be a cancellation point.

(My basic attitude is that adding new cancellation points is always the
Wrong Thing, and should only be done when _unavoidable_; and in this
particular case it is especially bad since applications are probably
going to assume that this function never fails, blocks, or even writes
fewer bytes than requested to the buffer, no matter how clearly we say
that it might.)

>> We don't normally do this at all.

> 

> See the “Evolution of ELF symbol management” thread.  We do it all the

> time, for the benefit of non-libc DSOs in the glibc conglomerate.  I

> think there is broad consensus that we need to extend this to libstdc++

> at least (in addition to changes needed to enable C++ compilation

> without _GNU_SOURCE).  And once we are at C++, why stop there?  Even

> dynamic languages with a C extension framework would use this.


See the reply I'm about to post in that thread.

zw
Florian Weimer Nov. 16, 2016, 3:52 p.m. UTC | #5
On 11/16/2016 04:20 PM, Zack Weinberg wrote:
> On 11/16/2016 10:11 AM, Florian Weimer wrote:

>> On 11/14/2016 07:29 PM, Zack Weinberg wrote:

>>> On 11/14/2016 12:44 PM, Florian Weimer wrote:

>>>> This patch switches back to the ssize_t return time.  This goes against

>>>> Theodore Ts'o preference, but seems to reflect the consensus from the

>>>> largery community.

>>>

>>> I still don't think this function should be a cancellation point.

>>

>> I guess we'll have to agree to disagree on this matter.

>

> I am seriously considering escalating my disagreement here to a formal

> objection.  I would like to know why you think it is NECESSARY - not

> merely convenient or consistent with other stuff - for this function to

> be a cancellation point.


It's necessary if you ever want to cancel a hanging getrandom in a 
context where you cannot install a signal handler (so that you can 
trigger EINTR when getrandom is stuck).

I really don't understand why cancellation points are widely considered 
as evil.  Most code does not use cancellation in a correct way, and it 
will not improve if we simply stop adding new cancellation points. 
Furthermore, it's easy to make a cancellation point go away (just switch 
the cancel state around the call), but at least in library code, it is 
impossible to introduce cancellation into a system call where the 
wrapper does not support it (because you cannot fake your own version of 
cancellation with a do-nothing signal handler).

Thanks,
Florian
Zack Weinberg Nov. 16, 2016, 4:41 p.m. UTC | #6
On Wed, Nov 16, 2016 at 10:52 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 11/16/2016 04:20 PM, Zack Weinberg wrote:

>> I am seriously considering escalating my disagreement here to a

>> formal objection.  I would like to know why you think it is

>> NECESSARY - not merely convenient or consistent with other stuff -

>> for this function to be a cancellation point.

>

> It's necessary if you ever want to cancel a hanging getrandom in a

> context where you cannot install a signal handler (so that you can

> trigger EINTR when getrandom is stuck).


That only pushes the question back a level.  When would it ever be
necessary to do that?  Be as concrete as you possibly can.  Actual
code from a real program, if possible.

> I really don't understand why cancellation points are widely

> considered as evil.  Most code does not use cancellation in a

> correct way, and it will not improve if we simply stop adding new

> cancellation points.


I would argue that most code does not use cancellation correctly in
large part _because_ the set of cancellation points is so large and
amorphous.  It is the same problem that people have with exceptions in
C++; because practically everything you might do exposes you to
cancellation, it's so difficult to know how to write cancel-safe code
that people just apply the big hammer of not using it at all.  Another
useful example is multithreading versus coroutines with explicit yield
points---the latter can be less efficient and/or more verbose, but
it's so much easier to debug that it's worth it.

There's not a lot we can do about the cancellation-point set in POSIX
being so large, but we can at least not make things worse, by not
adding additional cancellation points.

> at least in library code, it is impossible to introduce cancellation

> into a system call where the wrapper does not support it (because

> you cannot fake your own version of cancellation with a do-nothing

> signal handler).


From the perspective that as few operations as possible should be
cancellation points, this is a Good Thing.  And I don't see why it
would be a problem for getrandom in particular.

zw
Torvald Riegel Nov. 16, 2016, 6:02 p.m. UTC | #7
On Wed, 2016-11-16 at 16:52 +0100, Florian Weimer wrote:
> On 11/16/2016 04:20 PM, Zack Weinberg wrote:

> > On 11/16/2016 10:11 AM, Florian Weimer wrote:

> >> On 11/14/2016 07:29 PM, Zack Weinberg wrote:

> >>> On 11/14/2016 12:44 PM, Florian Weimer wrote:

> >>>> This patch switches back to the ssize_t return time.  This goes against

> >>>> Theodore Ts'o preference, but seems to reflect the consensus from the

> >>>> largery community.

> >>>

> >>> I still don't think this function should be a cancellation point.

> >>

> >> I guess we'll have to agree to disagree on this matter.

> >

> > I am seriously considering escalating my disagreement here to a formal

> > objection.  I would like to know why you think it is NECESSARY - not

> > merely convenient or consistent with other stuff - for this function to

> > be a cancellation point.

> 

> It's necessary if you ever want to cancel a hanging getrandom in a 

> context where you cannot install a signal handler (so that you can 

> trigger EINTR when getrandom is stuck).


I think it would be better to split the getrandom that is a cancellation
point into two functions, getrandom (not a cancellation point) and
getrandom_cancelable (is a cancellation point).  This way, the
functionality is available for programs but requires explicit opt-in,
while the default is not going to lead to surprises in the expected
common case (ie, when randomness is available).  I don't think the
opt-in is a problem because as you said, cancellation requires careful
programming anyway.
Adhemerval Zanella Nov. 16, 2016, 7:52 p.m. UTC | #8
On 16/11/2016 16:02, Torvald Riegel wrote:
> On Wed, 2016-11-16 at 16:52 +0100, Florian Weimer wrote:

>> On 11/16/2016 04:20 PM, Zack Weinberg wrote:

>>> On 11/16/2016 10:11 AM, Florian Weimer wrote:

>>>> On 11/14/2016 07:29 PM, Zack Weinberg wrote:

>>>>> On 11/14/2016 12:44 PM, Florian Weimer wrote:

>>>>>> This patch switches back to the ssize_t return time.  This goes against

>>>>>> Theodore Ts'o preference, but seems to reflect the consensus from the

>>>>>> largery community.

>>>>>

>>>>> I still don't think this function should be a cancellation point.

>>>>

>>>> I guess we'll have to agree to disagree on this matter.

>>>

>>> I am seriously considering escalating my disagreement here to a formal

>>> objection.  I would like to know why you think it is NECESSARY - not

>>> merely convenient or consistent with other stuff - for this function to

>>> be a cancellation point.

>>

>> It's necessary if you ever want to cancel a hanging getrandom in a 

>> context where you cannot install a signal handler (so that you can 

>> trigger EINTR when getrandom is stuck).

> 

> I think it would be better to split the getrandom that is a cancellation

> point into two functions, getrandom (not a cancellation point) and

> getrandom_cancelable (is a cancellation point).  This way, the

> functionality is available for programs but requires explicit opt-in,

> while the default is not going to lead to surprises in the expected

> common case (ie, when randomness is available).  I don't think the

> opt-in is a problem because as you said, cancellation requires careful

> programming anyway.

> 


I would advise against adding another symbol, it only adds complexity
and most likely one interface would be preferable from application
point of view.

Considering portability, why not following current approach from other
OS/libc? User will probably create more highly level interfaces based
underlying facilities, so I see trying to follow current interface
semantics in a non standard interface seems a better approach.

For instance, OpenBSD getentropy seems a to just direct syscall, so
not cancellation handling (src/libexec/ld.so/<architecture>/ldasm.S).
FreeBSD does not have a similar syscall, but provides a sysctl/KERN_ARND
that does basically the same.  I am not sure about Solaris.
Mike Frysinger Nov. 17, 2016, 6:21 a.m. UTC | #9
On 14 Nov 2016 18:44, Florian Weimer wrote:

just nits at this point

> +/* Flags for use with getrandom.  */

> +#define GRND_NONBLOCK 1

> +#define GRND_RANDOM 2


if they're bit flags, should we be doing 0x1/0x2 etc ?  otherwise this
will turn into 4, 8, 16, 32, 64, etc... which gets ugly.  the kernel
headers use hex constants.

> +/* Test getrandom with a single buffer length.  */

> +static void

> +test_length (char *buffer, size_t length, unsigned int flags)

> +{

> +  memset (buffer, 0, length);

> +  strcpy (buffer + length, "123");


while this works, it seems pointlessly fragile.  can't you treat it like
a normal "this is the length of the buffer" and carve out space at the
end yourself ?  i.e.
	memset (buffer, 0, length);
	static const char canary[] = "123";
	size_t canary_len = sizeof(canary);
	length -= canary_len;
	strcpy (buffer + length, canary);
	...

	ssize_t ret = getrandom (buffer, length - , flags);

> +  if (ret < 0)

> +    {

> +      if (!((flags & GRND_RANDOM)

> +            && (flags & GRND_NONBLOCK)

> +            && errno != EAGAIN))


seems like it'd be more readable to distribute the ! and to combine the
flags check into a single mask ?  i have to read these lines a few times
to digest what exactly the code is trying to do.

> +      if (getrandom_full (buffer1, sizeof (buffer1), flags)

> +          && getrandom_full (buffer2, sizeof (buffer2), flags))

> +        {

> +          if (memcmp (buffer1, buffer2, sizeof (buffer1)) == 0)


maybe also add a comment that likelihood of this being the same is
extremely rare too.

  return 77;
> +

> +  for (int use_random = 0; use_random < 2; ++use_random)

> +    for (int use_nonblock = 0; use_nonblock < 2; ++use_nonblock)

> +      {

> +        int flags = 0;


unsigned to match the API ?
-mike

> +        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 807e43d..f52e7e7 100644

> --- a/sysdeps/arm/nacl/libc.abilist

> +++ b/sysdeps/arm/nacl/libc.abilist

> @@ -1843,6 +1843,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 gnu_dev_major F

>  GLIBC_2.25 gnu_dev_makedev F

>  GLIBC_2.25 gnu_dev_minor F

> diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list

> index 2254c76..79483ea 100644

> --- a/sysdeps/unix/syscalls.list

> +++ b/sysdeps/unix/syscalls.list

> @@ -100,3 +100,4 @@ utimes		-	utimes		i:sp	__utimes	utimes

>  vhangup		-	vhangup		i:i	vhangup

>  write		-	write		Ci:ibn	__libc_write	__write write

>  writev		-	writev		Ci:ipi	__writev	writev

> +getrandom	-	getrandom	Ci:bni  __libc_getrandom	getrandom

> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist

> index 77accdf..77a2231 100644

> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist

> @@ -2090,6 +2090,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist

> index 659b7fc..922e7c3 100644

> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist

> @@ -2001,6 +2001,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist

> index 8bc979a..7831eb2 100644

> --- a/sysdeps/unix/sysv/linux/arm/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/arm/libc.abilist

> @@ -91,6 +91,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist

> index 299b705..f6623b7 100644

> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist

> @@ -1855,6 +1855,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist

> index f00345f..ef04a40 100644

> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist

> @@ -2013,6 +2013,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist

> index e5fcf88..37dde9d 100644

> --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist

> @@ -1877,6 +1877,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist

> index 8f382f6..b236ba8 100644

> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist

> @@ -92,6 +92,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist

> index 320b7fe..0983296 100644

> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist

> @@ -1969,6 +1969,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist

> index 21b1426..6cd5093 100644

> --- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist

> @@ -2090,6 +2090,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist

> index 5c4b596..67c0ce0 100644

> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist

> @@ -1944,6 +1944,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist

> index 001fa6c..88b9f5f 100644

> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist

> @@ -1942,6 +1942,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist

> index 2d87001..b2bfc81 100644

> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist

> @@ -1940,6 +1940,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist

> index aa1ee66..2cb3e46 100644

> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist

> @@ -1935,6 +1935,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist

> index 2471d68..bd3db24 100644

> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist

> @@ -2131,6 +2131,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist

> index 4b0cde8..317c8ba 100644

> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist

> @@ -1973,6 +1973,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist

> index 0557c16..0774b80 100644

> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist

> @@ -1978,6 +1978,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist

> index 821384e..174f8b2 100644

> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist

> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist

> @@ -2178,6 +2178,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist

> index c40a3f1..b364cae 100644

> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist

> @@ -92,6 +92,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist

> index 5b39a60..66168b9 100644

> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist

> @@ -1973,6 +1973,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist

> index a9db32f..0e99054 100644

> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist

> @@ -1874,6 +1874,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist

> index 294af0a..c47d2ac 100644

> --- a/sysdeps/unix/sysv/linux/sh/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/sh/libc.abilist

> @@ -1859,6 +1859,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist

> index 32747bd..923e598 100644

> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist

> @@ -1965,6 +1965,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist

> index b0ac4d4..836dabb 100644

> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist

> @@ -1903,6 +1903,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist

> index 4d92d81..2f7d425 100644

> --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist

> @@ -2097,6 +2097,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist

> index a68aef7..5a240a4 100644

> --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist

> @@ -2097,6 +2097,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist

> index 4d92d81..2f7d425 100644

> --- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist

> @@ -2097,6 +2097,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist

> index b8623fc..aa57670 100644

> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist

> @@ -1854,6 +1854,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F

> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist

> index a61d874..1a7bcea 100644

> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist

> @@ -2097,6 +2097,8 @@ GLIBC_2.23 fts64_set F

>  GLIBC_2.24 GLIBC_2.24 A

>  GLIBC_2.24 quick_exit F

>  GLIBC_2.25 GLIBC_2.25 A

> +GLIBC_2.25 __libc_getrandom F

> +GLIBC_2.25 getrandom F

>  GLIBC_2.25 strfromd F

>  GLIBC_2.25 strfromf F

>  GLIBC_2.25 strfroml F
Torvald Riegel Nov. 17, 2016, 12:52 p.m. UTC | #10
On Wed, 2016-11-16 at 17:52 -0200, Adhemerval Zanella wrote:
> 

> On 16/11/2016 16:02, Torvald Riegel wrote:

> > On Wed, 2016-11-16 at 16:52 +0100, Florian Weimer wrote:

> >> On 11/16/2016 04:20 PM, Zack Weinberg wrote:

> >>> On 11/16/2016 10:11 AM, Florian Weimer wrote:

> >>>> On 11/14/2016 07:29 PM, Zack Weinberg wrote:

> >>>>> On 11/14/2016 12:44 PM, Florian Weimer wrote:

> >>>>>> This patch switches back to the ssize_t return time.  This goes against

> >>>>>> Theodore Ts'o preference, but seems to reflect the consensus from the

> >>>>>> largery community.

> >>>>>

> >>>>> I still don't think this function should be a cancellation point.

> >>>>

> >>>> I guess we'll have to agree to disagree on this matter.

> >>>

> >>> I am seriously considering escalating my disagreement here to a formal

> >>> objection.  I would like to know why you think it is NECESSARY - not

> >>> merely convenient or consistent with other stuff - for this function to

> >>> be a cancellation point.

> >>

> >> It's necessary if you ever want to cancel a hanging getrandom in a 

> >> context where you cannot install a signal handler (so that you can 

> >> trigger EINTR when getrandom is stuck).

> > 

> > I think it would be better to split the getrandom that is a cancellation

> > point into two functions, getrandom (not a cancellation point) and

> > getrandom_cancelable (is a cancellation point).  This way, the

> > functionality is available for programs but requires explicit opt-in,

> > while the default is not going to lead to surprises in the expected

> > common case (ie, when randomness is available).  I don't think the

> > opt-in is a problem because as you said, cancellation requires careful

> > programming anyway.

> > 

> 

> I would advise against adding another symbol, it only adds complexity

> and most likely one interface would be preferable from application

> point of view.


We could add a parameter too that determines whether it is a
cancellation point.  That avoids your concern about adding another
symbol, and programmers will still have to make a conscious decision
about cancellation.  I don't see how this adds complexity; the
complexity in there is having to choose between the different semantics,
or be aware that it's just one of them when we know that just one of
them is not a one-size-fits-all for all use cases.
Florian Weimer Nov. 17, 2016, 1:02 p.m. UTC | #11
On 11/16/2016 05:41 PM, Zack Weinberg wrote:
> On Wed, Nov 16, 2016 at 10:52 AM, Florian Weimer <fweimer@redhat.com> wrote:

>> On 11/16/2016 04:20 PM, Zack Weinberg wrote:

>>> I am seriously considering escalating my disagreement here to a

>>> formal objection.  I would like to know why you think it is

>>> NECESSARY - not merely convenient or consistent with other stuff -

>>> for this function to be a cancellation point.

>>

>> It's necessary if you ever want to cancel a hanging getrandom in a

>> context where you cannot install a signal handler (so that you can

>> trigger EINTR when getrandom is stuck).

>

> That only pushes the question back a level.  When would it ever be

> necessary to do that?  Be as concrete as you possibly can.  Actual

> code from a real program, if possible.


It's not clear to me what you are asking here.

Do you mean cancellation in general, or cancellation in conjunction with 
getrandom specifically?

Thanks,
Florian
Zack Weinberg Nov. 17, 2016, 1:45 p.m. UTC | #12
On 11/17/2016 08:02 AM, Florian Weimer wrote:
> On 11/16/2016 05:41 PM, Zack Weinberg wrote:

>> On Wed, Nov 16, 2016 at 10:52 AM, Florian Weimer <fweimer@redhat.com>

>> wrote:

>>> On 11/16/2016 04:20 PM, Zack Weinberg wrote:

>>>> I am seriously considering escalating my disagreement here to a

>>>> formal objection.  I would like to know why you think it is

>>>> NECESSARY - not merely convenient or consistent with other stuff -

>>>> for this function to be a cancellation point.

>>>

>>> It's necessary if you ever want to cancel a hanging getrandom in a

>>> context where you cannot install a signal handler (so that you can

>>> trigger EINTR when getrandom is stuck).

>>

>> That only pushes the question back a level.  When would it ever be

>> necessary to do that?  Be as concrete as you possibly can.  Actual

>> code from a real program, if possible.

> 

> It's not clear to me what you are asking here.

> 

> Do you mean cancellation in general, or cancellation in conjunction with

> getrandom specifically?


Sorry.  I meant cancellation specifically of a thread hanging in getrandom.

zw
Florian Weimer Nov. 17, 2016, 1:50 p.m. UTC | #13
On 11/17/2016 02:45 PM, Zack Weinberg wrote:
> On 11/17/2016 08:02 AM, Florian Weimer wrote:

>> On 11/16/2016 05:41 PM, Zack Weinberg wrote:

>>> On Wed, Nov 16, 2016 at 10:52 AM, Florian Weimer <fweimer@redhat.com>

>>> wrote:

>>>> On 11/16/2016 04:20 PM, Zack Weinberg wrote:

>>>>> I am seriously considering escalating my disagreement here to a

>>>>> formal objection.  I would like to know why you think it is

>>>>> NECESSARY - not merely convenient or consistent with other stuff -

>>>>> for this function to be a cancellation point.

>>>>

>>>> It's necessary if you ever want to cancel a hanging getrandom in a

>>>> context where you cannot install a signal handler (so that you can

>>>> trigger EINTR when getrandom is stuck).

>>>

>>> That only pushes the question back a level.  When would it ever be

>>> necessary to do that?  Be as concrete as you possibly can.  Actual

>>> code from a real program, if possible.

>>

>> It's not clear to me what you are asking here.

>>

>> Do you mean cancellation in general, or cancellation in conjunction with

>> getrandom specifically?

>

> Sorry.  I meant cancellation specifically of a thread hanging in getrandom.


I'm not sure how I can provide that, considering that there is currently 
no way to cancel a thread which hangs in getrandom because we do not 
provide a way for applications to implement system calls as cancellation 
points (unless we provide a wrapper for the specific system call, of 
course).

Florian
Zack Weinberg Nov. 17, 2016, 1:56 p.m. UTC | #14
On 11/17/2016 08:50 AM, Florian Weimer wrote:
> On 11/17/2016 02:45 PM, Zack Weinberg wrote:

>> On 11/17/2016 08:02 AM, Florian Weimer wrote:

>>> On 11/16/2016 05:41 PM, Zack Weinberg wrote:

>>>> On Wed, Nov 16, 2016 at 10:52 AM, Florian Weimer <fweimer@redhat.com>

>>>> wrote:

>>>>> On 11/16/2016 04:20 PM, Zack Weinberg wrote:

>>>>>> I am seriously considering escalating my disagreement here to a

>>>>>> formal objection.  I would like to know why you think it is

>>>>>> NECESSARY - not merely convenient or consistent with other stuff -

>>>>>> for this function to be a cancellation point.

>>>>>

>>>>> It's necessary if you ever want to cancel a hanging getrandom in a

>>>>> context where you cannot install a signal handler (so that you can

>>>>> trigger EINTR when getrandom is stuck).

>>>>

>>>> That only pushes the question back a level.  When would it ever be

>>>> necessary to do that?  Be as concrete as you possibly can.  Actual

>>>> code from a real program, if possible.

>>>

>>> It's not clear to me what you are asking here.

>>>

>>> Do you mean cancellation in general, or cancellation in conjunction with

>>> getrandom specifically?

>>

>> Sorry.  I meant cancellation specifically of a thread hanging in

>> getrandom.

> 

> I'm not sure how I can provide that, considering that there is currently

> no way to cancel a thread which hangs in getrandom because we do not

> provide a way for applications to implement system calls as cancellation

> points (unless we provide a wrapper for the specific system call, of

> course).


What I'm asking for is evidence that that is actually a problem for at
least one real application.  Also evidence that making getrandom a
cancellation point _won't_ break programs that naively assume it can
never fail.

zw
Florian Weimer Nov. 17, 2016, 3:24 p.m. UTC | #15
On 11/17/2016 02:56 PM, Zack Weinberg wrote:
> On 11/17/2016 08:50 AM, Florian Weimer wrote:

>> On 11/17/2016 02:45 PM, Zack Weinberg wrote:

>>> On 11/17/2016 08:02 AM, Florian Weimer wrote:

>>>> On 11/16/2016 05:41 PM, Zack Weinberg wrote:

>>>>> On Wed, Nov 16, 2016 at 10:52 AM, Florian Weimer <fweimer@redhat.com>

>>>>> wrote:

>>>>>> On 11/16/2016 04:20 PM, Zack Weinberg wrote:

>>>>>>> I am seriously considering escalating my disagreement here to a

>>>>>>> formal objection.  I would like to know why you think it is

>>>>>>> NECESSARY - not merely convenient or consistent with other stuff -

>>>>>>> for this function to be a cancellation point.

>>>>>>

>>>>>> It's necessary if you ever want to cancel a hanging getrandom in a

>>>>>> context where you cannot install a signal handler (so that you can

>>>>>> trigger EINTR when getrandom is stuck).

>>>>>

>>>>> That only pushes the question back a level.  When would it ever be

>>>>> necessary to do that?  Be as concrete as you possibly can.  Actual

>>>>> code from a real program, if possible.

>>>>

>>>> It's not clear to me what you are asking here.

>>>>

>>>> Do you mean cancellation in general, or cancellation in conjunction with

>>>> getrandom specifically?

>>>

>>> Sorry.  I meant cancellation specifically of a thread hanging in

>>> getrandom.

>>

>> I'm not sure how I can provide that, considering that there is currently

>> no way to cancel a thread which hangs in getrandom because we do not

>> provide a way for applications to implement system calls as cancellation

>> points (unless we provide a wrapper for the specific system call, of

>> course).

>

> What I'm asking for is evidence that that is actually a problem for at

> least one real application.


I found this:

<https://opensource.apple.com/source/ppp/ppp-412.3/Helpers/vpnd/ipsecoptions.c>

ipsec_resolver_thread reads from /dev/random, which can block for a very 
long time.  The thread for it is spawned in ipsec_process_prefs, which 
cancels it when got_terminate returns true.  The intent seems to be that 
is terminated on graceful process termination: read in 
ipsec_process_prefs returns EINTR after a signal handler has run which 
makes got_terminate (defined in main.c in the parent directory) return true.

If the read from /dev/random is replaced with a call to getrandom which 
is not a cancellation point, this would like not work as intended.

Is this the kind of stuff you are looking for?

 > Also evidence that making getrandom a

> cancellation point _won't_ break programs that naively assume it can

> never fail.


Cancellation does not add additional error return cases.

Thanks,
Florian
Zack Weinberg Nov. 17, 2016, 5:16 p.m. UTC | #16
On 11/17/2016 10:24 AM, Florian Weimer wrote:
> On 11/17/2016 02:56 PM, Zack Weinberg wrote:

>>

>> What I'm asking for is evidence that that is actually a problem for at

>> least one real application.

> 

> I found this:

> 

> <https://opensource.apple.com/source/ppp/ppp-412.3/Helpers/vpnd/ipsecoptions.c>

> 

> ipsec_resolver_thread reads from /dev/random, which can block for a very

> long time.  The thread for it is spawned in ipsec_process_prefs, which

> cancels it when got_terminate returns true.  The intent seems to be that

> is terminated on graceful process termination: read in

> ipsec_process_prefs returns EINTR after a signal handler has run which

> makes got_terminate (defined in main.c in the parent directory) return

> true.


It seems to me that this code does not *need* to cancel the
ipsec_resolver_thread when it does, as it is about to call exit() [I
think] which will blow away all threads anyway.

>> Also evidence that making getrandom a

>> cancellation point _won't_ break programs that naively assume it can

>> never fail.

> 

> Cancellation does not add additional error return cases.


It does add additional _failure_ cases.  Suppose a program that expects
threads only to be at risk of cancellation at points where they do
network I/O, and does all the necessary dancing to make that reliable.
These threads are _already_ using getrandom() where available, via a
portability wrapper that will call into the C library if possible, or
make a direct syscall otherwise.  Being a wrapper, it's not a
cancellation point, and the surrounding code relies on that.  Now you
upgrade glibc, and suddenly getrandom() _is_ a cancellation point, and
the threads can now be cancelled in places where their data structures
are internally inconsistent -- and it doesn't matter that getrandom()
doesn't block under normal conditions, because the generic
cancel-testing code will fire anyway.

[This is just the general argument that adding new cancellation points
to the C library can render existing code buggy without notice.]

zw
Szabolcs Nagy Nov. 18, 2016, 8:28 a.m. UTC | #17
On 17/11/16 12:52, Torvald Riegel wrote:
> On Wed, 2016-11-16 at 17:52 -0200, Adhemerval Zanella wrote:

>>

>> On 16/11/2016 16:02, Torvald Riegel wrote:

>>> On Wed, 2016-11-16 at 16:52 +0100, Florian Weimer wrote:

>>>> On 11/16/2016 04:20 PM, Zack Weinberg wrote:

>>>>> On 11/16/2016 10:11 AM, Florian Weimer wrote:

>>>>>> On 11/14/2016 07:29 PM, Zack Weinberg wrote:

>>>>>>> On 11/14/2016 12:44 PM, Florian Weimer wrote:

>>>>>>>> This patch switches back to the ssize_t return time.  This goes against

>>>>>>>> Theodore Ts'o preference, but seems to reflect the consensus from the

>>>>>>>> largery community.

>>>>>>>

>>>>>>> I still don't think this function should be a cancellation point.

>>>>>>

>>>>>> I guess we'll have to agree to disagree on this matter.

>>>>>

>>>>> I am seriously considering escalating my disagreement here to a formal

>>>>> objection.  I would like to know why you think it is NECESSARY - not

>>>>> merely convenient or consistent with other stuff - for this function to

>>>>> be a cancellation point.

>>>>

>>>> It's necessary if you ever want to cancel a hanging getrandom in a 

>>>> context where you cannot install a signal handler (so that you can 

>>>> trigger EINTR when getrandom is stuck).

>>>

>>> I think it would be better to split the getrandom that is a cancellation

>>> point into two functions, getrandom (not a cancellation point) and

>>> getrandom_cancelable (is a cancellation point).  This way, the

>>> functionality is available for programs but requires explicit opt-in,

>>> while the default is not going to lead to surprises in the expected

>>> common case (ie, when randomness is available).  I don't think the

>>> opt-in is a problem because as you said, cancellation requires careful

>>> programming anyway.

>>>

>>

>> I would advise against adding another symbol, it only adds complexity

>> and most likely one interface would be preferable from application

>> point of view.

> 

> We could add a parameter too that determines whether it is a

> cancellation point.  That avoids your concern about adding another


why?

use pthread_setcancelstate.

works with all cancellation points not just getrandom.

> symbol, and programmers will still have to make a conscious decision

> about cancellation.  I don't see how this adds complexity; the

> complexity in there is having to choose between the different semantics,

> or be aware that it's just one of them when we know that just one of

> them is not a one-size-fits-all for all use cases.

>
Szabolcs Nagy Nov. 18, 2016, 10:27 a.m. UTC | #18
On 17/11/16 17:16, Zack Weinberg wrote:
> On 11/17/2016 10:24 AM, Florian Weimer wrote:

>> On 11/17/2016 02:56 PM, Zack Weinberg wrote:

>>> Also evidence that making getrandom a

>>> cancellation point _won't_ break programs that naively assume it can

>>> never fail.

>>

>> Cancellation does not add additional error return cases.

> 

> It does add additional _failure_ cases.  Suppose a program that expects

> threads only to be at risk of cancellation at points where they do

> network I/O, and does all the necessary dancing to make that reliable.

> These threads are _already_ using getrandom() where available, via a

> portability wrapper that will call into the C library if possible, or

> make a direct syscall otherwise.  Being a wrapper, it's not a

> cancellation point, and the surrounding code relies on that.  Now you

> upgrade glibc, and suddenly getrandom() _is_ a cancellation point, and

> the threads can now be cancelled in places where their data structures

> are internally inconsistent -- and it doesn't matter that getrandom()

> doesn't block under normal conditions, because the generic

> cancel-testing code will fire anyway.

> 

> [This is just the general argument that adding new cancellation points

> to the C library can render existing code buggy without notice.]


there is no existing code that uses glibc getrandom.

a user can easily turn a cancellation point into
a non-cancellation one if desired, but the other
way is not possible.

blocking syscalls have to be cancellation points
otherwise they cannot be called safely from a long
running process that has to remain responsive:
blocked threads can keep piling up and there is no
way to reuse the resources they hold.

[this is the general argument for adding new
blocking syscalls as cancellation points].
Florian Weimer Nov. 18, 2016, 1:21 p.m. UTC | #19
On 11/17/2016 07:21 AM, Mike Frysinger wrote:
> On 14 Nov 2016 18:44, Florian Weimer wrote:

>

> just nits at this point

>

>> +/* Flags for use with getrandom.  */

>> +#define GRND_NONBLOCK 1

>> +#define GRND_RANDOM 2

>

> if they're bit flags, should we be doing 0x1/0x2 etc ?  otherwise this

> will turn into 4, 8, 16, 32, 64, etc... which gets ugly.  the kernel

> headers use hex constants.


Okay, I turned this into:

#define GRND_NONBLOCK 0x01
#define GRND_RANDOM 0x02

Do you want more zero padding?

(I'm not a fan of column alignment because it means that future patches 
will have to make whitespace-only changes to change column alignment, 
which slightly obfuscates the actual change.)

>> +/* Test getrandom with a single buffer length.  */

>> +static void

>> +test_length (char *buffer, size_t length, unsigned int flags)

>> +{

>> +  memset (buffer, 0, length);

>> +  strcpy (buffer + length, "123");

>

> while this works, it seems pointlessly fragile.  can't you treat it like

> a normal "this is the length of the buffer" and carve out space at the

> end yourself ?  i.e.


> 	memset (buffer, 0, length);

> 	static const char canary[] = "123";

> 	size_t canary_len = sizeof(canary);

> 	length -= canary_len;

> 	strcpy (buffer + length, canary);

> 	...

>

> 	ssize_t ret = getrandom (buffer, length - , flags);


I don't think this is much clearer.  I'm going to add a comment:

/* Test getrandom with a single buffer length.  NB: The passed-in
    buffer must have room for four extra bytes after the specified
    length, which are used to test that getrandom leaves those bytes
    unchanged.  */

Hopefully this is clear enough.

>

>> +  if (ret < 0)

>> +    {

>> +      if (!((flags & GRND_RANDOM)

>> +            && (flags & GRND_NONBLOCK)

>> +            && errno != EAGAIN))

>

> seems like it'd be more readable to distribute the ! and to combine the

> flags check into a single mask ?  i have to read these lines a few times

> to digest what exactly the code is trying to do.


What about this?

       /* EAGAIN is an expected error with GRND_RANDOM and
          GRND_NONBLOCK.  */
       if ((flags & GRND_RANDOM)
           && (flags & GRND_NONBLOCK)
           && errno == EAGAIN)
         return;
       printf ("error: getrandom (%zu, 0x%x): %m\n", length, flags);
       errors = true;
       return;

The second return was missing before, the old condition was actually wrong.

>> +      if (getrandom_full (buffer1, sizeof (buffer1), flags)

>> +          && getrandom_full (buffer2, sizeof (buffer2), flags))

>> +        {

>> +          if (memcmp (buffer1, buffer2, sizeof (buffer1)) == 0)

>

> maybe also add a comment that likelihood of this being the same is

> extremely rare too.


This should do it:

           /* The probability that these two 8-byte buffers are equal
              is very small (assuming that two subsequent calls to
              getrandom result are independent, uniformly distributed
              random variables).  */

>> +  for (int use_random = 0; use_random < 2; ++use_random)

>> +    for (int use_nonblock = 0; use_nonblock < 2; ++use_nonblock)

>> +      {

>> +        int flags = 0;

>

> unsigned to match the API ?


Right, thanks.

Do you have any comments about the matter of the cancellation point and 
the redirect to __libc_getrandom?

Thanks,
florian
Torvald Riegel Nov. 18, 2016, 2:21 p.m. UTC | #20
On Fri, 2016-11-18 at 08:28 +0000, Szabolcs Nagy wrote:
> On 17/11/16 12:52, Torvald Riegel wrote:

> > On Wed, 2016-11-16 at 17:52 -0200, Adhemerval Zanella wrote:

> >>

> >> On 16/11/2016 16:02, Torvald Riegel wrote:

> >>> On Wed, 2016-11-16 at 16:52 +0100, Florian Weimer wrote:

> >>>> On 11/16/2016 04:20 PM, Zack Weinberg wrote:

> >>>>> On 11/16/2016 10:11 AM, Florian Weimer wrote:

> >>>>>> On 11/14/2016 07:29 PM, Zack Weinberg wrote:

> >>>>>>> On 11/14/2016 12:44 PM, Florian Weimer wrote:

> >>>>>>>> This patch switches back to the ssize_t return time.  This goes against

> >>>>>>>> Theodore Ts'o preference, but seems to reflect the consensus from the

> >>>>>>>> largery community.

> >>>>>>>

> >>>>>>> I still don't think this function should be a cancellation point.

> >>>>>>

> >>>>>> I guess we'll have to agree to disagree on this matter.

> >>>>>

> >>>>> I am seriously considering escalating my disagreement here to a formal

> >>>>> objection.  I would like to know why you think it is NECESSARY - not

> >>>>> merely convenient or consistent with other stuff - for this function to

> >>>>> be a cancellation point.

> >>>>

> >>>> It's necessary if you ever want to cancel a hanging getrandom in a 

> >>>> context where you cannot install a signal handler (so that you can 

> >>>> trigger EINTR when getrandom is stuck).

> >>>

> >>> I think it would be better to split the getrandom that is a cancellation

> >>> point into two functions, getrandom (not a cancellation point) and

> >>> getrandom_cancelable (is a cancellation point).  This way, the

> >>> functionality is available for programs but requires explicit opt-in,

> >>> while the default is not going to lead to surprises in the expected

> >>> common case (ie, when randomness is available).  I don't think the

> >>> opt-in is a problem because as you said, cancellation requires careful

> >>> programming anyway.

> >>>

> >>

> >> I would advise against adding another symbol, it only adds complexity

> >> and most likely one interface would be preferable from application

> >> point of view.

> > 

> > We could add a parameter too that determines whether it is a

> > cancellation point.  That avoids your concern about adding another

> 

> why?

> 

> use pthread_setcancelstate.

> 

> works with all cancellation points not just getrandom.


As discussed in the thread, there are different opinions about what the
default should be.  There are reasonable arguments for both options.  In
such a case, it seems better to make the choice explicit, simply from an
ease-of-use and interface design perspective.  This is not about whether
it's possible for users to do (they could build their own syscall
wrappers after all too, right? ;) ) but about clean interfaces.

With your proposal, one could argue that, for example, every library has
to be aware of cancellation and how it works if one of the clients of
the library could want to use cancellation; the library either has to
disable it explicitly, or it has to document which additional
cancellation points exist and has to implement the cleanup handlers.
This is error-prone and adds complexity to those use cases.  Therefore,
it seems better to avoid that potential source of bugs and either make
the default to not support cancellation (ie, an opt-in for the
cancellation facility), or make at least make the choice explicit for
users of getrandom (ie, two functions or an additional parameter).
Florian Weimer Nov. 18, 2016, 3:13 p.m. UTC | #21
On 11/18/2016 03:21 PM, Torvald Riegel wrote:

> As discussed in the thread, there are different opinions about what the

> default should be.  There are reasonable arguments for both options.  In

> such a case, it seems better to make the choice explicit, simply from an

> ease-of-use and interface design perspective.


Unfortunately, this is not the approach that POSIX has chosen.  But 
there is precedent for doing our own thing in this area: the "c" flag 
for fopen.  We cannot use the existing flags argument in getrandom for 
this purpose because its layout is controlled by the kernel.

> This is not about whether

> it's possible for users to do (they could build their own syscall

> wrappers after all too, right? ;) ) but about clean interfaces.


It's not possible to opt in to cancellation at system calls using only 
public glibc interfaces.  The best you can do is to implement 
cancellation from scratch, using a different signal.

> With your proposal, one could argue that, for example, every library has

> to be aware of cancellation and how it works if one of the clients of

> the library could want to use cancellation;


But that is true for most libraries today, no matter what we do about 
getrandom.  getrandom just does not add significant additional exposure 
in this area.

> the library either has to

> disable it explicitly, or it has to document which additional

> cancellation points exist and has to implement the cleanup handlers.

> This is error-prone and adds complexity to those use cases.  Therefore,

> it seems better to avoid that potential source of bugs and either make

> the default to not support cancellation (ie, an opt-in for the

> cancellation facility), or make at least make the choice explicit for

> users of getrandom (ie, two functions or an additional parameter).


I'm increasingly worried that this discussion is actually about thread 
cancellation in general and only peripherally about getrandom. 
Considering the fringe nature of getrandom (it is intended for the 
implementation of PRNG seeding, after all), it seems to be a strange 
choice to attempt to settle this debate.

Does POSIX even say that cancellation has to be enabled for new threads 
by default, like we do?  It's probably too late to change this.

In the end, this is very similar to the ongoing debate about exception 
handling in C++ and other languages.  For most such languages, there are 
large code bases which ban exceptions for various reasons, and others 
which use them with success.  I don't think we can reach agreement which 
one application developers should prefer.  The only thing we can do is 
try to be as consistent as possible (and for getrandom, I think the 
model should be the read function, and not rand).

This discussion is also blocking further work on my part for additional 
randomness generation functions.  More user-oriented interfaces we could 
add, such as getentropy or arc4random, should *not* be cancellation 
points, I think.

Thanks,
Florian
Torvald Riegel Nov. 18, 2016, 3:46 p.m. UTC | #22
On Fri, 2016-11-18 at 10:27 +0000, Szabolcs Nagy wrote:
> blocking syscalls have to be cancellation points

> otherwise they cannot be called safely from a long

> running process that has to remain responsive:

> blocked threads can keep piling up and there is no

> way to reuse the resources they hold.

> 

> [this is the general argument for adding new

> blocking syscalls as cancellation points].


You are describing just *one* use case.

You also don't define what "remain responsive" is supposed to mean;
there's a difference between being able to cancel any time vs. ensuring
that a syscall will not block indefinitely (eg, I think the common case
for getrandom should be that it does not block indefinitely, and
scenarios in which no randomness can be found nor "generated" are corner
cases).

Related to that, you don't distinguish between what can be done to
recover when a particular syscall does not complete; for example, is
there likely to be a workaround for a getrandom that does complete, or
is calling exit() the most likely response.

You also don't discuss who the expected audience for a syscall wrapper
is. How likely it is that they are aware of cancellation, might make use
of it, etc.?  How likely is the syscall going to be used directly vs.
being hidden by another wrapper that is produced by developers that
understand cancellation?

Just the fact that there are all these different considerations suggests
that there's no clean one-size-fits-all interface.  Hence my suggestion
to at least make the choice explicit (and thus obvious to users), for
example by either an additional parameter or by providing two
wrappers.  

If there is in fact no good default or one-size-fits-all, we should not
pretend that there is.

Finally, pthreads cancellation is a pretty crude means to build
asynchronous / cancellable operations because you cannot cancel just a
particular call; you always cancel a thread, which means that in
general, you need additional synchronization or other constraints to
make sure that you do not cancel at another cancellation point in some
other unrelated operation executed by the same thread.
Torvald Riegel Nov. 18, 2016, 4:04 p.m. UTC | #23
On Fri, 2016-11-18 at 16:13 +0100, Florian Weimer wrote:
> On 11/18/2016 03:21 PM, Torvald Riegel wrote:

> 

> > As discussed in the thread, there are different opinions about what the

> > default should be.  There are reasonable arguments for both options.  In

> > such a case, it seems better to make the choice explicit, simply from an

> > ease-of-use and interface design perspective.

> 

> Unfortunately, this is not the approach that POSIX has chosen.  But 

> there is precedent for doing our own thing in this area: the "c" flag 

> for fopen.  We cannot use the existing flags argument in getrandom for 

> this purpose because its layout is controlled by the kernel.


It seems a separate argument would be better than using up space in the
existing flags.  Cancellation is something we add, so we should add to
the underlying interface too, instead of messing with it.

> > This is not about whether

> > it's possible for users to do (they could build their own syscall

> > wrappers after all too, right? ;) ) but about clean interfaces.

> 

> It's not possible to opt in to cancellation at system calls using only 

> public glibc interfaces.  The best you can do is to implement 

> cancellation from scratch, using a different signal.


I agree with that, but I was replying specifically to Scabolcs' comment
that users would have to just disable cancellation around a cancelable
syscall wrapper.

> > With your proposal, one could argue that, for example, every library has

> > to be aware of cancellation and how it works if one of the clients of

> > the library could want to use cancellation;

> 

> But that is true for most libraries today, no matter what we do about 

> getrandom.  getrandom just does not add significant additional exposure 

> in this area.


That's not true for a library that just wraps getrandom functionality.
I think that we should care about that independently of whether the same
problem exists elsewhere, unless it's clear that users will always have
to face the problem (eg, if getrandom would only be usable when also
doing file I/O at the same time).

> > the library either has to

> > disable it explicitly, or it has to document which additional

> > cancellation points exist and has to implement the cleanup handlers.

> > This is error-prone and adds complexity to those use cases.  Therefore,

> > it seems better to avoid that potential source of bugs and either make

> > the default to not support cancellation (ie, an opt-in for the

> > cancellation facility), or make at least make the choice explicit for

> > users of getrandom (ie, two functions or an additional parameter).

> 

> I'm increasingly worried that this discussion is actually about thread 

> cancellation in general and only peripherally about getrandom. 

> Considering the fringe nature of getrandom (it is intended for the 

> implementation of PRNG seeding, after all), it seems to be a strange 

> choice to attempt to settle this debate.


I can understand that you feel burdened by the wider debate, but I'm
also not convinced that we can ignore it just because it does something
that will be executed rarely.  I think the fringe nature might even be
an argument for having to be more careful about cancellation: If
getrandom in that corner over there, far away from other uses of
cancellation, how likely is it that users of it are aware of
cancellation at all?

> Does POSIX even say that cancellation has to be enabled for new threads 

> by default, like we do?  It's probably too late to change this.

> 

> In the end, this is very similar to the ongoing debate about exception 

> handling in C++ and other languages.  For most such languages, there are 

> large code bases which ban exceptions for various reasons, and others 

> which use them with success.  I don't think we can reach agreement which 

> one application developers should prefer.  The only thing we can do is 

> try to be as consistent as possible (and for getrandom, I think the 

> model should be the read function, and not rand).


I don't think this is a clean analogy.

> This discussion is also blocking further work on my part for additional 

> randomness generation functions.  More user-oriented interfaces we could 

> add, such as getentropy or arc4random, should *not* be cancellation 

> points, I think.


That's unfortunate, I agree.

What I haven't seen so far is a convincing argument why we should not
make the choice of cancellation point or not explicit in the wrapper.
Some have voiced broad concerns about the number of symbols (but is this
really such a big deal?), but I haven't seen an argument yet which
expressed detailed concerns about adding a separate argument that
determines whether there is cancellation point or not.

If we can't decide on one solution, mostly because we expect there to be
different use cases and users, why should we try to force a decision
instead of exposing the choice? -- especially given the point you make
about this being a very specialized syscall.
Zack Weinberg Nov. 18, 2016, 6:50 p.m. UTC | #24
On Fri, Nov 18, 2016 at 5:27 AM, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote:
> On 17/11/16 17:16, Zack Weinberg wrote:

>> [This is just the general argument that adding new cancellation points

>> to the C library can render existing code buggy without notice.]

>

> there is no existing code that uses glibc getrandom.

>

> a user can easily turn a cancellation point into

> a non-cancellation one if desired, but the other

> way is not possible.


I specifically said there was a wrapper that anticipates the
availability of glibc getrandom, and uses a direct syscall in the
meantime.  AC_REPLACE_FUNCS(getrandom) or dlsym("getrandom") or like
that.

> blocking syscalls have to be cancellation points

> otherwise they cannot be called safely from a long

> running process that has to remain responsive:

> blocked threads can keep piling up and there is no

> way to reuse the resources they hold.


This is a valid point - I personally read it as an argument against
adding any new blocking syscalls, but that's not the world we live in.

I don't want to derail this into a general debate over adding new
cancellation points, and I especially don't want to hold up work on a
user-space CSPRNG on something unrelated, because arc4random() is the
top item on _my_ todo list after explicit_bzero().  So here is a
counterproposal.  Most of my concerns about getrandom() being a
cancellation point go away if it is only a cancellation point when it
is actually going to block -- note that I very much do _not_ mean
"when it is called with arguments that permit it to block."  How about
we have the public getrandom do like this:

ssize_t getrandom (void *buffer, size_t length, unsigned int flags)
{
  ssize_t rv = __getrandom_nocancel (buffer, length, flags | GRND_NONBLOCK);
  if (rv == length)
    return rv;
  if (rv < 0 && ((flags & GRND_NONBLOCK) || errno != EAGAIN)
    return rv;
  rv = max(rv, 0);
  return __getrandom_maycancel (buffer + rv, length - rv, flags);
}

I could live with that.

zw
Torvald Riegel Nov. 21, 2016, 4:57 p.m. UTC | #25
On Fri, 2016-11-18 at 13:50 -0500, Zack Weinberg wrote:
> I don't want to derail this into a general debate over adding new

> cancellation points, and I especially don't want to hold up work on a

> user-space CSPRNG on something unrelated, because arc4random() is the

> top item on _my_ todo list after explicit_bzero().  So here is a

> counterproposal.  Most of my concerns about getrandom() being a

> cancellation point go away if it is only a cancellation point when it

> is actually going to block


Is there a way for the caller to ensure that a subsequent call to
getrandom is not going to block?  If there isn't, then the caller has to
conservatively assume that the call may be a cancellation point.

I still think something like 
ssize_t getrandom (/*getrandom parameters*/, bool cancellation_point);  
would probably be the best option because it requires a caller to make a
conscious decision about cancellation (and thus also makes the caller
aware of the whole cancellation thing).
Zack Weinberg Nov. 21, 2016, 5:12 p.m. UTC | #26
On Mon, Nov 21, 2016 at 11:57 AM, Torvald Riegel <triegel@redhat.com> wrote:
> On Fri, 2016-11-18 at 13:50 -0500, Zack Weinberg wrote:

>> I don't want to derail this into a general debate over adding new

>> cancellation points, and I especially don't want to hold up work on a

>> user-space CSPRNG on something unrelated, because arc4random() is the

>> top item on _my_ todo list after explicit_bzero().  So here is a

>> counterproposal.  Most of my concerns about getrandom() being a

>> cancellation point go away if it is only a cancellation point when it

>> is actually going to block

>

> Is there a way for the caller to ensure that a subsequent call to

> getrandom is not going to block?  If there isn't, then the caller has to

> conservatively assume that the call may be a cancellation point.


The whole reason I can live with my proposal is that most code should
be able to assume getrandom *never* blocks.  Specifically, if
getrandom ever blocks once we're past a fairly early stage of boot-up,
that's a bug in either the kernel or the setup procedure.  (I'd *like*
to get to where the kernel wouldn't even start process 1 until it
could guarantee that the RNG would not block, but that's a long way
off.)  So the only code that has to worry about it is early-stage boot
code that has to be written hyper-defensively anyway.

zw
Torvald Riegel Nov. 21, 2016, 5:30 p.m. UTC | #27
On Mon, 2016-11-21 at 12:12 -0500, Zack Weinberg wrote:
> On Mon, Nov 21, 2016 at 11:57 AM, Torvald Riegel <triegel@redhat.com> wrote:

> > On Fri, 2016-11-18 at 13:50 -0500, Zack Weinberg wrote:

> >> I don't want to derail this into a general debate over adding new

> >> cancellation points, and I especially don't want to hold up work on a

> >> user-space CSPRNG on something unrelated, because arc4random() is the

> >> top item on _my_ todo list after explicit_bzero().  So here is a

> >> counterproposal.  Most of my concerns about getrandom() being a

> >> cancellation point go away if it is only a cancellation point when it

> >> is actually going to block

> >

> > Is there a way for the caller to ensure that a subsequent call to

> > getrandom is not going to block?  If there isn't, then the caller has to

> > conservatively assume that the call may be a cancellation point.

> 

> The whole reason I can live with my proposal is that most code should

> be able to assume getrandom *never* blocks.  Specifically, if

> getrandom ever blocks once we're past a fairly early stage of boot-up,

> that's a bug in either the kernel or the setup procedure.


Does the kernel guarantee this, meaning that it's specifically
documented as part of the interface?  Or similarly, does it give a
guarantee under some precondition (which systemd or similar guarantees
to establish)?
I understand why you think this would be useful behavior, but the
"should be able" part in your statement is too vague for us to rely on.

Also, what do you mean specifically by "block"?  If it is just taking a
relatively long time, but will always eventually finish irrespective of
whether other processes do or do not do something, then I wouldn't
classify the behavior as blocking.
Florian Weimer Nov. 21, 2016, 5:34 p.m. UTC | #28
On 11/21/2016 06:30 PM, Torvald Riegel wrote:

> Does the kernel guarantee this, meaning that it's specifically

> documented as part of the interface?


Yes, if the flags argument is 0, the call will only block if the kernel 
randomness pool has not been seeded yet.  And this is the reason why 
people want getrandom: they want to stop reading potentially predictable 
bits from /dev/urandom.

This is documented in the manual page.

Florian
Florian Weimer Nov. 29, 2016, 8:16 a.m. UTC | #29
On 11/18/2016 05:04 PM, Torvald Riegel wrote:
> On Fri, 2016-11-18 at 16:13 +0100, Florian Weimer wrote:

>> On 11/18/2016 03:21 PM, Torvald Riegel wrote:

>>

>>> As discussed in the thread, there are different opinions about what the

>>> default should be.  There are reasonable arguments for both options.  In

>>> such a case, it seems better to make the choice explicit, simply from an

>>> ease-of-use and interface design perspective.

>>

>> Unfortunately, this is not the approach that POSIX has chosen.  But

>> there is precedent for doing our own thing in this area: the "c" flag

>> for fopen.  We cannot use the existing flags argument in getrandom for

>> this purpose because its layout is controlled by the kernel.

>

> It seems a separate argument would be better than using up space in the

> existing flags.  Cancellation is something we add, so we should add to

> the underlying interface too, instead of messing with it.


Is this separate argument your personal preference, or are you just 
trying to find common ground and reconcile different positions?

Thanks,
Florian
Florian Weimer Nov. 29, 2016, 8:24 a.m. UTC | #30
On 11/18/2016 07:50 PM, Zack Weinberg wrote:

> I don't want to derail this into a general debate over adding new

> cancellation points,  and I especially don't want to hold up work on a

> user-space CSPRNG on something unrelated, because arc4random() is the

> top item on _my_ todo list after explicit_bzero().  So here is a

> counterproposal.  Most of my concerns about getrandom() being a

> cancellation point go away if it is only a cancellation point when it

> is actually going to block -- note that I very much do _not_ mean

> "when it is called with arguments that permit it to block."  How about

> we have the public getrandom do like this:

>

> ssize_t getrandom (void *buffer, size_t length, unsigned int flags)

> {

>   ssize_t rv = __getrandom_nocancel (buffer, length, flags | GRND_NONBLOCK);

>   if (rv == length)

>     return rv;

>   if (rv < 0 && ((flags & GRND_NONBLOCK) || errno != EAGAIN)

>     return rv;

>   rv = max(rv, 0);

>   return __getrandom_maycancel (buffer + rv, length - rv, flags);

> }


This is an intriguing idea, but it actually makes reasoning about 
cancellation more difficult, particularly with GRND_RANDOM.

I haven't seen a rationale for the POSIX design (in which cancellation 
points always check for cancellation, even if they don't block).  I 
suspect it goes something like this: If thread cancellation happens on 
only blocking, then whether cancellation occurs depends on a race: the 
cancellation has to occur while being blocked.  This might never happen. 
  It's hard to tell whether you actually can cancel threads doing this 
(when cancellation is desired), or that they do not get canceled 
accidentally.

Thanks,
Florian
Torvald Riegel Nov. 29, 2016, 1:56 p.m. UTC | #31
On Tue, 2016-11-29 at 09:16 +0100, Florian Weimer wrote:
> On 11/18/2016 05:04 PM, Torvald Riegel wrote:

> > On Fri, 2016-11-18 at 16:13 +0100, Florian Weimer wrote:

> >> On 11/18/2016 03:21 PM, Torvald Riegel wrote:

> >>

> >>> As discussed in the thread, there are different opinions about what the

> >>> default should be.  There are reasonable arguments for both options.  In

> >>> such a case, it seems better to make the choice explicit, simply from an

> >>> ease-of-use and interface design perspective.

> >>

> >> Unfortunately, this is not the approach that POSIX has chosen.  But

> >> there is precedent for doing our own thing in this area: the "c" flag

> >> for fopen.  We cannot use the existing flags argument in getrandom for

> >> this purpose because its layout is controlled by the kernel.

> >

> > It seems a separate argument would be better than using up space in the

> > existing flags.  Cancellation is something we add, so we should add to

> > the underlying interface too, instead of messing with it.

> 

> Is this separate argument your personal preference, or are you just 

> trying to find common ground and reconcile different positions?


It's my personal preference.  Which is partially motivated by trying to
find common ground between the different use cases (and not finding
obvious common group, so therefore make the choice explicit).
Florian Weimer Nov. 29, 2016, 2:40 p.m. UTC | #32
On 11/29/2016 02:56 PM, Torvald Riegel wrote:
> On Tue, 2016-11-29 at 09:16 +0100, Florian Weimer wrote:

>> On 11/18/2016 05:04 PM, Torvald Riegel wrote:

>>> On Fri, 2016-11-18 at 16:13 +0100, Florian Weimer wrote:

>>>> On 11/18/2016 03:21 PM, Torvald Riegel wrote:

>>>>

>>>>> As discussed in the thread, there are different opinions about what the

>>>>> default should be.  There are reasonable arguments for both options.  In

>>>>> such a case, it seems better to make the choice explicit, simply from an

>>>>> ease-of-use and interface design perspective.

>>>>

>>>> Unfortunately, this is not the approach that POSIX has chosen.  But

>>>> there is precedent for doing our own thing in this area: the "c" flag

>>>> for fopen.  We cannot use the existing flags argument in getrandom for

>>>> this purpose because its layout is controlled by the kernel.

>>>

>>> It seems a separate argument would be better than using up space in the

>>> existing flags.  Cancellation is something we add, so we should add to

>>> the underlying interface too, instead of messing with it.

>>

>> Is this separate argument your personal preference, or are you just

>> trying to find common ground and reconcile different positions?

>

> It's my personal preference.  Which is partially motivated by trying to

> find common ground between the different use cases (and not finding

> obvious common group, so therefore make the choice explicit).


Hmph.

I was about to propose a new patch, with two functions:

getrandom, as I posted it the last time (an unadorned system call which 
is also a cancellation point).

getentropy, a thin wrapper which avoids returning EINTR (to match 
OpenBSD and Solaris) and is not a cancellation point.  It would return 
EIO on short reads, too.

The documentation would have said that getrandom is a lower-level 
function for those which need GRND_RANDOM or cancellation, and everyone 
else should call getrandom.

Would this work for you?

Thanks,
Florian
Torvald Riegel Nov. 29, 2016, 3:23 p.m. UTC | #33
On Tue, 2016-11-29 at 15:40 +0100, Florian Weimer wrote:
> On 11/29/2016 02:56 PM, Torvald Riegel wrote:

> > On Tue, 2016-11-29 at 09:16 +0100, Florian Weimer wrote:

> >> On 11/18/2016 05:04 PM, Torvald Riegel wrote:

> >>> On Fri, 2016-11-18 at 16:13 +0100, Florian Weimer wrote:

> >>>> On 11/18/2016 03:21 PM, Torvald Riegel wrote:

> >>>>

> >>>>> As discussed in the thread, there are different opinions about what the

> >>>>> default should be.  There are reasonable arguments for both options.  In

> >>>>> such a case, it seems better to make the choice explicit, simply from an

> >>>>> ease-of-use and interface design perspective.

> >>>>

> >>>> Unfortunately, this is not the approach that POSIX has chosen.  But

> >>>> there is precedent for doing our own thing in this area: the "c" flag

> >>>> for fopen.  We cannot use the existing flags argument in getrandom for

> >>>> this purpose because its layout is controlled by the kernel.

> >>>

> >>> It seems a separate argument would be better than using up space in the

> >>> existing flags.  Cancellation is something we add, so we should add to

> >>> the underlying interface too, instead of messing with it.

> >>

> >> Is this separate argument your personal preference, or are you just

> >> trying to find common ground and reconcile different positions?

> >

> > It's my personal preference.  Which is partially motivated by trying to

> > find common ground between the different use cases (and not finding

> > obvious common group, so therefore make the choice explicit).

> 

> Hmph.


Note that I mean that this is my preference specifically in the scenario
of adding some sort of flag to getrandom() and offering only
getrandom().

> I was about to propose a new patch, with two functions:

> 

> getrandom, as I posted it the last time (an unadorned system call which 

> is also a cancellation point).

> 

> getentropy, a thin wrapper which avoids returning EINTR (to match 

> OpenBSD and Solaris) and is not a cancellation point.  It would return 

> EIO on short reads, too.

> 

> The documentation would have said that getrandom is a lower-level 

> function for those which need GRND_RANDOM or cancellation, and everyone 

> else should call getrandom.


I guess one of these should be getentropy (the latter?).

> Would this work for you?


Yeah, I guess so.  I can't really estimate how obvious it would be for
users to have to consider the pair of these (and thus make a conscious
choice and understand what cancellation means) -- but if we can make
this fairly obvious (eg, through proper documentation) and thus are
likely to prevent users from making a mistake, and we have an
alternative for the non-cancellation use case, then I guess this could
be a meaningful solution.
Florian Weimer Nov. 29, 2016, 3:32 p.m. UTC | #34
On 11/29/2016 04:23 PM, Torvald Riegel wrote:
> On Tue, 2016-11-29 at 15:40 +0100, Florian Weimer wrote:

>> On 11/29/2016 02:56 PM, Torvald Riegel wrote:

>>> On Tue, 2016-11-29 at 09:16 +0100, Florian Weimer wrote:

>>>> On 11/18/2016 05:04 PM, Torvald Riegel wrote:

>>>>> On Fri, 2016-11-18 at 16:13 +0100, Florian Weimer wrote:

>>>>>> On 11/18/2016 03:21 PM, Torvald Riegel wrote:

>>>>>>

>>>>>>> As discussed in the thread, there are different opinions about what the

>>>>>>> default should be.  There are reasonable arguments for both options.  In

>>>>>>> such a case, it seems better to make the choice explicit, simply from an

>>>>>>> ease-of-use and interface design perspective.

>>>>>>

>>>>>> Unfortunately, this is not the approach that POSIX has chosen.  But

>>>>>> there is precedent for doing our own thing in this area: the "c" flag

>>>>>> for fopen.  We cannot use the existing flags argument in getrandom for

>>>>>> this purpose because its layout is controlled by the kernel.

>>>>>

>>>>> It seems a separate argument would be better than using up space in the

>>>>> existing flags.  Cancellation is something we add, so we should add to

>>>>> the underlying interface too, instead of messing with it.

>>>>

>>>> Is this separate argument your personal preference, or are you just

>>>> trying to find common ground and reconcile different positions?

>>>

>>> It's my personal preference.  Which is partially motivated by trying to

>>> find common ground between the different use cases (and not finding

>>> obvious common group, so therefore make the choice explicit).

>>

>> Hmph.

>

> Note that I mean that this is my preference specifically in the scenario

> of adding some sort of flag to getrandom() and offering only

> getrandom().

>

>> I was about to propose a new patch, with two functions:

>>

>> getrandom, as I posted it the last time (an unadorned system call which

>> is also a cancellation point).

>>

>> getentropy, a thin wrapper which avoids returning EINTR (to match

>> OpenBSD and Solaris) and is not a cancellation point.  It would return

>> EIO on short reads, too.

>>

>> The documentation would have said that getrandom is a lower-level

>> function for those which need GRND_RANDOM or cancellation, and everyone

>> else should call getrandom.

>

> I guess one of these should be getentropy (the latter?).


Yes, developers should prefer getentropy or a PRNG seeded from getentropy.

>> Would this work for you?

>

> Yeah, I guess so.  I can't really estimate how obvious it would be for

> users to have to consider the pair of these (and thus make a conscious

> choice and understand what cancellation means) -- but if we can make

> this fairly obvious (eg, through proper documentation) and thus are

> likely to prevent users from making a mistake, and we have an

> alternative for the non-cancellation use case, then I guess this could

> be a meaningful solution.


Great.

Zack, what do you think?

Thanks,
Florian
Zack Weinberg Nov. 29, 2016, 3:54 p.m. UTC | #35
On Tue, Nov 29, 2016 at 10:32 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 11/29/2016 04:23 PM, Torvald Riegel wrote:

>>

>> On Tue, 2016-11-29 at 15:40 +0100, Florian Weimer wrote:

>>>

>>> I was about to propose a new patch, with two functions:

>>>

>>> getrandom, as I posted it the last time (an unadorned system call which

>>> is also a cancellation point).

>>>

>>> getentropy, a thin wrapper which avoids returning EINTR (to match

>>> OpenBSD and Solaris) and is not a cancellation point.  It would return

>>> EIO on short reads, too.

>>>

>>> The documentation would have said that getrandom is a lower-level

>>> function for those which need GRND_RANDOM or cancellation, and everyone

>>> else should call getrandom.

>>

>> I guess one of these should be getentropy (the latter?).

>

> Yes, developers should prefer getentropy or a PRNG seeded from getentropy.

>

>>> Would this work for you?

>>

>>

>> Yeah, I guess so.  I can't really estimate how obvious it would be for

>> users to have to consider the pair of these (and thus make a conscious

>> choice and understand what cancellation means) -- but if we can make

>> this fairly obvious (eg, through proper documentation) and thus are

>> likely to prevent users from making a mistake, and we have an

>> alternative for the non-cancellation use case, then I guess this could

>> be a meaningful solution.

>

> Great.

>

> Zack, what do you think?


Yeah, this would also work for me.  Would it make sense for getentropy
to loop internally rather than returning a short read?  I am really
worried about people forgetting to handle short reads.

zw
Paul Eggert Nov. 29, 2016, 5:53 p.m. UTC | #36
On 11/29/2016 07:54 AM, Zack Weinberg wrote:
> Would it make sense for getentropy

> to loop internally rather than returning a short read?


FWIW, that is what I was planning when implementing a more-portable 
version of getentropy (I guess that's its name now?) for Gnulib, after 
the API settles down. Gnulib-using applications typically need a small 
number of random bytes. I don't want to worry about modifying these apps 
to take into account the possibility of waiting indefinitely due to a 
bug in the hardware or operating system. If such a wait occurs, it's OK 
with me to just say "fix your platform".
Florian Weimer Nov. 29, 2016, 6:11 p.m. UTC | #37
On 11/29/2016 06:53 PM, Paul Eggert wrote:
> On 11/29/2016 07:54 AM, Zack Weinberg wrote:

>> Would it make sense for getentropy

>> to loop internally rather than returning a short read?

>

> FWIW, that is what I was planning when implementing a more-portable

> version of getentropy (I guess that's its name now?) for Gnulib,


How are you going to avoid interposing the implementation in glibc?

Thanks,
Florian
Paul Eggert Nov. 29, 2016, 7:37 p.m. UTC | #38
On 11/29/2016 10:11 AM, Florian Weimer wrote:
> How are you going to avoid interposing the implementation in glibc? 


That will depend on how glibc is implemented. Simplest might be to use 
compile-time interposition, which is common in Gnulib. E.g., Gnulib 
would supply its own getentropy.h which does "#define getentropy 
rpl_getentropy", so that Gnulib-using applications always call 
rpl_getentropy from the linker's point of view. This sort of thing is OK 
for Gnulib, as it's not intended to be a separate library.
Florian Weimer Nov. 30, 2016, 6:09 a.m. UTC | #39
On 11/29/2016 08:37 PM, Paul Eggert wrote:
> On 11/29/2016 10:11 AM, Florian Weimer wrote:

>> How are you going to avoid interposing the implementation in glibc?

>

> That will depend on how glibc is implemented. Simplest might be to use

> compile-time interposition, which is common in Gnulib. E.g., Gnulib

> would supply its own getentropy.h which does "#define getentropy

> rpl_getentropy", so that Gnulib-using applications always call

> rpl_getentropy from the linker's point of view. This sort of thing is OK

> for Gnulib, as it's not intended to be a separate library.


This sounds reasonable, thanks.

Florian
diff mbox

Patch

Add getrandom system call and <sys/random.h> header file [BZ #17252]

2016-11-14  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.25): Add getrandom, __libc_getrandom.
	* stdlib/getrandom.c: New file.
	* stdlib/tst-getrandom.c: Likewise.
	* manual/crypt.texi (Unpredictable Bytes): New section.
	* manual/math.texi (Pseudo-Random Numbers): Add cross-reference.
	* sysdeps/arm/nacl/libc.abilist: Add __libc_getrandom, 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 65184b1..40f3ce4 100644
--- a/NEWS
+++ b/NEWS
@@ -67,6 +67,8 @@  Version 2.25
 * The functions strfromd, strfromf, and strfroml, from ISO/IEC TS 18661-1:2014,
   are added to libc.  They convert a floating-point number into string.
 
+* The getrandom function and the <sys/random.h> header file have been added.
+
 * The <sys/quota.h> header now includes the <linux/quota.h> header.  Support
   for the Linux quota interface which predates kernel version 2.4.22 has
   been removed.
diff --git a/manual/crypt.texi b/manual/crypt.texi
index 9f44740..f99b8be 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,69 @@  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 success, 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
+
+The @code{getrandom} function is a cancellation point.
+
+Even access to the non-blocking pool can block if the system has just
+booted and the pool has not yet been initialized.
+
+The @code{getrandom} function can fail with several errors, some of
+which are listed below.  In addition, the function may not fill the
+buffer completely and return a value less than @var{length}.
+
+@table @code
+@item ENOSYS
+The kernel does not implement the @code{getrandom} system call.
+
+@item EAGAIN
+No random data was available and @code{GRND_NONBLOCK} was specified in
+@var{flags}.
+
+@item EFAULT
+The combination of @var{buffer} and @var{length} arguments specifies
+an invalid memory range.
+
+@item EINTR
+The system call was interrupted.  During the system boot process, before
+the kernel randomness pool is initialized, this can happen even if
+@var{flags} is zero.
+
+@item EINVAL
+The @var{flags} argument contains an invalid combination of flags.
+@end table
+
+@end deftypefun
diff --git a/manual/math.texi b/manual/math.texi
index b4bb323..6c0d460 100644
--- a/manual/math.texi
+++ b/manual/math.texi
@@ -1414,7 +1414,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 3cce9d9..6c4ed22 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						      \
 	strfromf strfromd strfroml					      \
 	strtol strtoul strtoll strtoull					      \
 	strtol_l strtoul_l strtoll_l strtoull_l				      \
@@ -79,7 +79,8 @@  tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   tst-setcontext3 tst-tls-atexit-nodelete		    \
 		   tst-strtol-locale tst-strtod-nan-locale tst-strfmon_l    \
 		   tst-quick_exit tst-thread-quick_exit tst-width	    \
-		   tst-width-stdint tst-strfrom tst-strfrom-locale
+		   tst-width-stdint tst-strfrom tst-strfrom-locale \
+		   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 54416b7..15905cf 100644
--- a/stdlib/Versions
+++ b/stdlib/Versions
@@ -115,6 +115,7 @@  libc {
   GLIBC_2.25 {
     # s*
     strfromd; strfromf; strfroml;
+    getrandom; __libc_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..a7288eb
--- /dev/null
+++ b/stdlib/getrandom.c
@@ -0,0 +1,33 @@ 
+/* 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
+__libc_getrandom (void *buffer, size_t length, unsigned int flags)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+
+stub_warning (__libc_getrandom)
+
+weak_alias (__libc_getrandom, getrandom)
diff --git a/stdlib/sys/random.h b/stdlib/sys/random.h
new file mode 100644
index 0000000..4d2874f
--- /dev/null
+++ b/stdlib/sys/random.h
@@ -0,0 +1,51 @@ 
+/* 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
+
+#include <features.h>
+#include <sys/types.h>
+
+/* Flags for use with getrandom.  */
+#define GRND_NONBLOCK 1
+#define GRND_RANDOM 2
+
+__BEGIN_DECLS
+
+/* Write LENGTH bytes of randomness starting at BUFFER.  Returns the
+   number of bytes written, or -1 on error.  */
+#ifdef __REDIRECT
+/* For GNU compilers: Redirect getrandom to __libc_getrandom, to
+   protect against accidental interposition.  (Application code should
+   still use the getrandom symbol.)  */
+ssize_t __libc_getrandom (void *__buffer, size_t __length,
+                          unsigned int __flags) __wur;
+extern ssize_t __REDIRECT (getrandom,
+                       (void *__buffer, size_t __length,
+                        unsigned int __flags),
+                       __libc_getrandom);
+#else
+/* Non-GNU compilers call getrandom instead.  */
+ssize_t getrandom (void *__buffer, size_t __length, unsigned int __flags)
+  __wur;
+#endif /* __REDIRECT */
+
+__END_DECLS
+
+#endif /* _SYS_RANDOM_H */
diff --git a/stdlib/tst-getrandom.c b/stdlib/tst-getrandom.c
new file mode 100644
index 0000000..d8816b8
--- /dev/null
+++ b/stdlib/tst-getrandom.c
@@ -0,0 +1,166 @@ 
+/* 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, size_t length, unsigned int 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 (%zu, 0x%x): %m\n", length, flags);
+          errors = true;
+        }
+    }
+  if (ret != length)
+    {
+      if (flags & GRND_RANDOM)
+        {
+          if (ret == 0 || ret > length)
+            {
+              printf ("error: getrandom (%zu, 0x%x) returned %zd\n",
+                      length, flags, ret);
+              errors = true;
+            }
+        }
+      else
+        {
+          printf ("error: getrandom (%zu, 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 (%zu, 0x%x) returned all-zero bytes\n",
+                  length, flags);
+          errors = true;
+        }
+    }
+  if (memcmp (buffer + length, "123", 4) != 0)
+    {
+      printf ("error: getrandom (%zu, 0x%x) wrote spurious bytes\n",
+              length, flags);
+      errors = true;
+    }
+}
+
+/* Call getrandom repeatedly to fill the buffer.  */
+static bool
+getrandom_full (char *buffer, size_t length, unsigned int flags)
+{
+  char *end = buffer + length;
+  while (buffer < end)
+    {
+      ssize_t ret = getrandom (buffer, end - buffer, flags);
+      if (ret < 0)
+        {
+          printf ("error: getrandom (%zu, 0x%x): %m\n", length, flags);
+          errors = true;
+          return false;
+        }
+      buffer += ret;
+    }
+
+  return true;
+}
+
+static void
+test_flags (unsigned int 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 (buffer2, sizeof (buffer2), flags))
+        {
+          if (memcmp (buffer1, buffer2, sizeof (buffer1)) == 0)
+            {
+              printf ("error: getrandom returns constant value\n");
+              errors = true;
+            }
+        }
+    }
+}
+
+static int
+do_test (void)
+{
+  /* Check if getrandom is not supported by this system.  */
+  if (getrandom (NULL, 0, 0) == -1 && errno == ENOSYS)
+    return 77;
+
+  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 807e43d..f52e7e7 100644
--- a/sysdeps/arm/nacl/libc.abilist
+++ b/sysdeps/arm/nacl/libc.abilist
@@ -1843,6 +1843,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 gnu_dev_major F
 GLIBC_2.25 gnu_dev_makedev F
 GLIBC_2.25 gnu_dev_minor F
diff --git a/sysdeps/unix/syscalls.list b/sysdeps/unix/syscalls.list
index 2254c76..79483ea 100644
--- a/sysdeps/unix/syscalls.list
+++ b/sysdeps/unix/syscalls.list
@@ -100,3 +100,4 @@  utimes		-	utimes		i:sp	__utimes	utimes
 vhangup		-	vhangup		i:i	vhangup
 write		-	write		Ci:ibn	__libc_write	__write write
 writev		-	writev		Ci:ipi	__writev	writev
+getrandom	-	getrandom	Ci:bni  __libc_getrandom	getrandom
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 77accdf..77a2231 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2090,6 +2090,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 659b7fc..922e7c3 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2001,6 +2001,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
index 8bc979a..7831eb2 100644
--- a/sysdeps/unix/sysv/linux/arm/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
@@ -91,6 +91,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 299b705..f6623b7 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -1855,6 +1855,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index f00345f..ef04a40 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2013,6 +2013,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index e5fcf88..37dde9d 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1877,6 +1877,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 8f382f6..b236ba8 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -92,6 +92,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 320b7fe..0983296 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -1969,6 +1969,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
index 21b1426..6cd5093 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
@@ -2090,6 +2090,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 5c4b596..67c0ce0 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -1944,6 +1944,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 001fa6c..88b9f5f 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -1942,6 +1942,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 2d87001..b2bfc81 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -1940,6 +1940,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index aa1ee66..2cb3e46 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1935,6 +1935,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 2471d68..bd3db24 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2131,6 +2131,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index 4b0cde8..317c8ba 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -1973,6 +1973,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 0557c16..0774b80 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -1978,6 +1978,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
index 821384e..174f8b2 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2178,6 +2178,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index c40a3f1..b364cae 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -92,6 +92,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 5b39a60..66168b9 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -1973,6 +1973,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index a9db32f..0e99054 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1874,6 +1874,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
index 294af0a..c47d2ac 100644
--- a/sysdeps/unix/sysv/linux/sh/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
@@ -1859,6 +1859,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 32747bd..923e598 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -1965,6 +1965,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index b0ac4d4..836dabb 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1903,6 +1903,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
index 4d92d81..2f7d425 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
@@ -2097,6 +2097,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
index a68aef7..5a240a4 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
@@ -2097,6 +2097,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
index 4d92d81..2f7d425 100644
--- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
@@ -2097,6 +2097,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index b8623fc..aa57670 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1854,6 +1854,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index a61d874..1a7bcea 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2097,6 +2097,8 @@  GLIBC_2.23 fts64_set F
 GLIBC_2.24 GLIBC_2.24 A
 GLIBC_2.24 quick_exit F
 GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getrandom F
 GLIBC_2.25 strfromd F
 GLIBC_2.25 strfromf F
 GLIBC_2.25 strfroml F