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();
}
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> v(length);
int len = 0;
/* use "/dev/[u]random" by default in case of
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)
size_t offset;
for (offset = 0; offset < length; )
{
const int fd = open("/dev/urandom", O_RDONLY);
if (fd < 0 ||
(len = read(fd, v.data(), length)) < 0 ||
std::size_t(len) < length)
int b = read(getURandom(), v.data() + offset, length - offset);
if (b <= 0)
{
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();
if (errno == EINTR)
continue;
break;
}
if (fd >= 0)
close(fd);
offset += b;
}
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;

View File

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