Random re-work: keep a file-descriptor open to /dev/urandom

This should be inherited by forked children, and kept alive at all
times. If we have it already open everywhere, there seems little
benefit to the getrandom / getentropy system calls.

Change-Id: I5d58f7216c65febd161cbd78c24308d9192830ee
Signed-off-by: Michael Meeks <michael.meeks@collabora.com>
pull/8704/head
Michael Meeks 2024-04-06 12:42:36 +01:00 committed by Andras Timar
parent 29ef73868f
commit 7311352dd6
2 changed files with 34 additions and 30 deletions

View File

@ -113,43 +113,44 @@ namespace Util
return _rng(); return _rng();
} }
int getURandom()
{
static int urandom = open("/dev/urandom", O_RDONLY);
if (urandom < 0)
{
LOG_SYS("Failed to source hard random numbers");
fprintf(stderr, "No adequate source of randomness");
abort();
// Potentially dangerous to continue without randomness
}
return urandom;
}
// Since we have a fd always open to /dev/urandom
// 'read' is hopefully no less efficient than getrandom.
std::vector<char> getBytes(const std::size_t length) std::vector<char> getBytes(const std::size_t length)
{ {
std::vector<char> v(length); std::vector<char> v(length);
int len = 0; size_t offset;
/* use "/dev/[u]random" by default in case of for (offset = 0; offset < length; )
getentropy() or getrandom() fails,
or they don't available */
bool useDevRandom = true;
#ifdef HAVE_GETENTROPY
len = getentropy(v.data(), length);
// getentropy() works, no need to use "/dev/[u]random"
if (len != -1)
useDevRandom = false;
#elif defined HAVE_SYS_RANDOM_H
len = getrandom(v.data(), length, GRND_NONBLOCK);
// getrandom() works, no need to use "/dev/[u]random"
if (len != -1)
useDevRandom = false;
#endif
if (useDevRandom)
{ {
const int fd = open("/dev/urandom", O_RDONLY); int b = read(getURandom(), v.data() + offset, length - offset);
if (fd < 0 || if (b <= 0)
(len = read(fd, v.data(), length)) < 0 ||
std::size_t(len) < length)
{ {
fprintf(stderr, "No adequate source of randomness, " if (errno == EINTR)
"failed to read %ld bytes: with error %s\n", continue;
(long int)length, strerror(errno)); break;
// Potentially dangerous to continue without randomness
abort();
} }
if (fd >= 0) offset += b;
close(fd); }
if (offset < length)
{
fprintf(stderr, "No adequate source of randomness, "
"failed to read %ld bytes: with error %s\n",
(long int)length, strerror(errno));
// Potentially dangerous to continue without randomness
abort();
} }
return v; return v;

View File

@ -85,6 +85,9 @@ namespace Util
{ {
namespace rng namespace rng
{ {
/// Returns a global handle to /dev/urandom - do not close it.
int getURandom();
uint_fast64_t getSeed(); uint_fast64_t getSeed();
void reseed(); void reseed();
unsigned getNext(); unsigned getNext();