getentropy(3): Trap non-API errnos from getrandom(2) and abort

Additionally, reconcile our abort behavior with arc4random(3).  Unlike
SIGABRT, SIGKILL cannot be caught by the user program.  These failures
are fatal conditions and should not return to the caller, as they did in
the instance that resulted in D17049.

While here, fix some minor typos in a comment.

Reviewed by:	delphij
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D17050
This commit is contained in:
cem 2018-10-20 21:45:17 +00:00
parent a2a619aa9f
commit 71ddf40fef

View File

@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <errno.h>
#include <signal.h>
#include <stdbool.h>
#include <stdlib.h>
@ -44,6 +45,12 @@ __FBSDID("$FreeBSD$");
extern int __sysctl(int *, u_int, void *, size_t *, void *, size_t);
static inline void
_getentropy_fail(void)
{
raise(SIGKILL);
}
static size_t
arnd_sysctl(u_char *buf, size_t size)
{
@ -87,14 +94,14 @@ getentropy_fallback(void *buf, size_t buflen)
if (errno == EFAULT)
return (-1);
/*
* This cannot happen. _arc4_sysctl() spins until the random
* This cannot happen. arnd_sysctl() spins until the random
* device is seeded and then repeatedly reads until the full
* request is satisfied. The only way for this to return a zero
* byte or short read is if sysctl(2) on the kern.arandom MIB
* fails. In this case, exceping the user-provided-a-bogus-
* fails. In this case, excepting the user-provided-a-bogus-
* buffer EFAULT, give up (like for arc4random(3)'s arc4_stir).
*/
abort();
_getentropy_fail();
}
return (0);
}
@ -129,8 +136,10 @@ getentropy(void *buf, size_t buflen)
continue;
case EINTR:
continue;
default:
case EFAULT:
return (-1);
default:
_getentropy_fail();
}
}
} else {
@ -139,7 +148,7 @@ getentropy(void *buf, size_t buflen)
/* This cannot happen. */
if (rd == 0)
abort();
_getentropy_fail();
buf = (char *)buf + rd;
buflen -= rd;