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

Florian Weimer fweimer@redhat.com
Tue Nov 29 08:24:00 GMT 2016


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



More information about the Libc-alpha mailing list