Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/native/minipal/configure.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ check_function_exists(sysctlbyname HAVE_SYSCTLBYNAME)
check_function_exists(fsync HAVE_FSYNC)

check_symbol_exists(arc4random_buf "stdlib.h" HAVE_ARC4RANDOM_BUF)
check_symbol_exists(getrandom "sys/random.h" HAVE_GETRANDOM)
check_symbol_exists(O_CLOEXEC fcntl.h HAVE_O_CLOEXEC)
check_symbol_exists(CLOCK_MONOTONIC time.h HAVE_CLOCK_MONOTONIC)
check_symbol_exists(CLOCK_MONOTONIC_COARSE time.h HAVE_CLOCK_MONOTONIC_COARSE)
Expand Down
1 change: 1 addition & 0 deletions src/native/minipal/minipalconfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define HAVE_MINIPAL_MINIPALCONFIG_H

#cmakedefine01 HAVE_ARC4RANDOM_BUF
#cmakedefine01 HAVE_GETRANDOM
#cmakedefine01 HAVE_AUXV_HWCAP_H
#cmakedefine01 HAVE_HWPROBE_H
#cmakedefine01 HAVE_RESOURCE_H
Expand Down
42 changes: 42 additions & 0 deletions src/native/minipal/random.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#if HAVE_GETRANDOM
#include <sys/random.h>
#endif
#endif
#if defined(__APPLE__) && __APPLE__
#include <CommonCrypto/CommonRandom.h>
Expand Down Expand Up @@ -100,6 +103,45 @@ int32_t minipal_get_cryptographically_secure_random_bytes(uint8_t* buffer, int32
return BCRYPT_SUCCESS(status) ? 0 : -1;
#else

#if HAVE_GETRANDOM
// Try getrandom() first - it's faster than /dev/urandom as it avoids file descriptor overhead.
// getrandom() was added in Linux 3.17 (2014) and glibc 2.25 (2017).
static volatile bool sGetrandomUnavailable;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could we use the same terminology as is there below for devurandom, e.g. sMissingGetrandom?


if (!sGetrandomUnavailable)
{
int32_t offset = 0;
while (offset != bufferLength)
{
ssize_t n = getrandom(buffer + offset, (size_t)(bufferLength - offset), 0);
if (n == -1)
{
if (errno == EINTR)
{
continue;
}
// ENOSYS: syscall not available (old kernel or blocked by seccomp)
// EPERM: operation not permitted (some container environments)
// Fall back to /dev/urandom for these errors
if (errno == ENOSYS || errno == EPERM)
{
sGetrandomUnavailable = true;
break;
}
return -1;
}

offset += (int32_t)n;
}

if (offset == bufferLength)
{
return 0;
}
}
#endif

// Fallback to /dev/urandom
static volatile int rand_des = -1;
static bool sMissingDevURandom;

Expand Down
Loading