In r331279 the code used ENOSYS to check the existence of getrandom(2).
This will only work if the caller already handles SIGSYS, which is not always the case. Address this by checking osreldate instead. Note that because there was not __FreeBSD_version bump when the system call was added, use 1200061 (r332100) which is the first bump after the introduction of the system call. PR: 230762 Reported by: Jenkins via Mark Millard Reviewed by: cem Differential Revision: https://reviews.freebsd.org/D16807
This commit is contained in:
parent
beacffb30d
commit
59488f25ad
@ -34,10 +34,14 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libc_private.h"
|
||||
|
||||
/* First __FreeBSD_version bump after introduction of getrandom(2) (r331279) */
|
||||
#define GETRANDOM_FIRST 1200061
|
||||
|
||||
extern int __sysctl(int *, u_int, void *, size_t *, void *, size_t);
|
||||
|
||||
static size_t
|
||||
@ -99,21 +103,38 @@ int
|
||||
getentropy(void *buf, size_t buflen)
|
||||
{
|
||||
ssize_t rd;
|
||||
bool have_getrandom;
|
||||
|
||||
if (buflen > 256) {
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
have_getrandom = (__getosreldate() >= GETRANDOM_FIRST);
|
||||
|
||||
while (buflen > 0) {
|
||||
rd = getrandom(buf, buflen, 0);
|
||||
if (rd == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
else if (errno == ENOSYS || errno == ECAPMODE)
|
||||
return (getentropy_fallback(buf, buflen));
|
||||
else
|
||||
return (-1);
|
||||
if (have_getrandom) {
|
||||
rd = getrandom(buf, buflen, 0);
|
||||
if (rd == -1) {
|
||||
switch (errno) {
|
||||
case ECAPMODE:
|
||||
/*
|
||||
* Kernel >= r331280 and < r337999
|
||||
* will return ECAPMODE when the
|
||||
* caller is already in capability
|
||||
* mode, fallback to traditional
|
||||
* method in this case.
|
||||
*/
|
||||
have_getrandom = false;
|
||||
continue;
|
||||
case EINTR:
|
||||
continue;
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return (getentropy_fallback(buf, buflen));
|
||||
}
|
||||
|
||||
/* This cannot happen. */
|
||||
|
Loading…
Reference in New Issue
Block a user