[PATCH v2] arc4random: simplify design for better safety
Mark Harris
mark.hsj@gmail.com
Tue Jul 26 01:10:06 GMT 2022
Jason A. Donenfeld wrote:
> + l = __getrandom_nocancel (p, n, 0);
> + if (l > 0)
> + {
> + if ((size_t) l == n)
> + return; /* Done reading, success. */
> + p = (uint8_t *) p + l;
> + n -= l;
> + continue; /* Interrupted by a signal; keep going. */
> + }
> + else if (l == 0)
> + arc4random_getrandom_failure (); /* Weird, should never happen. */
> + else if (errno == ENOSYS)
> + {
> + have_getrandom = false;
> + break; /* No syscall, so fallback to /dev/urandom. */
> + }
> + arc4random_getrandom_failure (); /* Unknown error, should never happen. */
Isn't EINTR also possible? Aborting in that case does not seem reasonable.
Also the __getrandom_nocancel function does not set errno on Linux; it
just returns INTERNAL_SYSCALL_CALL (getrandom, buf, buflen, flags).
So unless that is changed, it doesn't look like this ENOSYS check will
detect old Linux kernels.
> + struct pollfd pfd = { .events = POLLIN };
> + pfd.fd = TEMP_FAILURE_RETRY (
> + __open64_nocancel ("/dev/random", O_RDONLY | O_CLOEXEC | O_NOCTTY));
> + if (pfd.fd < 0)
> + arc4random_getrandom_failure ();
> + if (__poll (&pfd, 1, -1) < 0)
> + arc4random_getrandom_failure ();
> + if (__close_nocancel (pfd.fd) < 0)
> + arc4random_getrandom_failure ();
The TEMP_FAILURE_RETRY handles EINTR on open, but __poll can also
result in EINTR.
- Mark
More information about the Libc-alpha
mailing list