This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH v7] getrandom system call wrapper [BZ #17252]
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