mirror of
https://github.com/ruby/ruby.git
synced 2026-01-26 12:14:51 +00:00
merge revision(s) 1181a682a6c314c92686e3701defa1eb44068c4e, d84a811f31a65821642b165d712f380c0cc060e0: [Backport #21448]
[Bug #21448] Use `getentropy(2)` only on macOS If this is not a system call, then it is using getrandom (which would have been tried already), and cannot be used as a replacement for the random devices. [Bug #21448] Reorder trials in `fill_random_bytes` First try dedicated system calls, such as `getrandom` or `getentropy`, next possible libraries, then fallback to `/dev/urandom`.
This commit is contained in:
parent
f0f97886fc
commit
508daebdcd
76
random.c
76
random.c
@ -438,23 +438,17 @@ random_init(int argc, VALUE *argv, VALUE obj)
|
||||
# define USE_DEV_URANDOM 0
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETENTROPY
|
||||
# define MAX_SEED_LEN_PER_READ 256
|
||||
static int
|
||||
fill_random_bytes_urandom(void *seed, size_t size)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)seed;
|
||||
while (size) {
|
||||
size_t len = size < MAX_SEED_LEN_PER_READ ? size : MAX_SEED_LEN_PER_READ;
|
||||
if (getentropy(p, len) != 0) {
|
||||
return -1;
|
||||
}
|
||||
p += len;
|
||||
size -= len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#elif USE_DEV_URANDOM
|
||||
#if ! defined HAVE_GETRANDOM && defined __linux__ && defined __NR_getrandom
|
||||
# ifndef GRND_NONBLOCK
|
||||
# define GRND_NONBLOCK 0x0001 /* not defined in musl libc */
|
||||
# endif
|
||||
# define getrandom(ptr, size, flags) \
|
||||
(ssize_t)syscall(__NR_getrandom, (ptr), (size), (flags))
|
||||
# define HAVE_GETRANDOM 1
|
||||
#endif
|
||||
|
||||
/* fill random bytes by reading random device directly */
|
||||
#if USE_DEV_URANDOM
|
||||
static int
|
||||
fill_random_bytes_urandom(void *seed, size_t size)
|
||||
{
|
||||
@ -494,15 +488,7 @@ fill_random_bytes_urandom(void *seed, size_t size)
|
||||
# define fill_random_bytes_urandom(seed, size) -1
|
||||
#endif
|
||||
|
||||
#if ! defined HAVE_GETRANDOM && defined __linux__ && defined __NR_getrandom
|
||||
# ifndef GRND_NONBLOCK
|
||||
# define GRND_NONBLOCK 0x0001 /* not defined in musl libc */
|
||||
# endif
|
||||
# define getrandom(ptr, size, flags) \
|
||||
(ssize_t)syscall(__NR_getrandom, (ptr), (size), (flags))
|
||||
# define HAVE_GETRANDOM 1
|
||||
#endif
|
||||
|
||||
/* fill random bytes by library */
|
||||
#if 0
|
||||
#elif defined MAC_OS_X_VERSION_10_7 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7
|
||||
|
||||
@ -520,7 +506,7 @@ fill_random_bytes_urandom(void *seed, size_t size)
|
||||
# endif
|
||||
|
||||
static int
|
||||
fill_random_bytes_syscall(void *seed, size_t size, int unused)
|
||||
fill_random_bytes_lib(void *seed, size_t size)
|
||||
{
|
||||
#if USE_COMMON_RANDOM
|
||||
CCRNGStatus status = CCRandomGenerateBytes(seed, size);
|
||||
@ -549,7 +535,7 @@ fill_random_bytes_syscall(void *seed, size_t size, int unused)
|
||||
}
|
||||
#elif defined(HAVE_ARC4RANDOM_BUF)
|
||||
static int
|
||||
fill_random_bytes_syscall(void *buf, size_t size, int unused)
|
||||
fill_random_bytes_lib(void *buf, size_t size)
|
||||
{
|
||||
#if (defined(__OpenBSD__) && OpenBSD >= 201411) || \
|
||||
(defined(__NetBSD__) && __NetBSD_Version__ >= 700000000) || \
|
||||
@ -638,11 +624,17 @@ fill_random_bytes_bcrypt(void *seed, size_t size)
|
||||
}
|
||||
|
||||
static int
|
||||
fill_random_bytes_syscall(void *seed, size_t size, int unused)
|
||||
fill_random_bytes_lib(void *seed, size_t size)
|
||||
{
|
||||
if (fill_random_bytes_bcrypt(seed, size) == 0) return 0;
|
||||
return fill_random_bytes_crypt(seed, size);
|
||||
}
|
||||
#else
|
||||
# define fill_random_bytes_lib(seed, size) -1
|
||||
#endif
|
||||
|
||||
/* fill random bytes by dedicated syscall */
|
||||
#if 0
|
||||
#elif defined HAVE_GETRANDOM
|
||||
static int
|
||||
fill_random_bytes_syscall(void *seed, size_t size, int need_secure)
|
||||
@ -666,6 +658,31 @@ fill_random_bytes_syscall(void *seed, size_t size, int need_secure)
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#elif defined(HAVE_GETENTROPY)
|
||||
/*
|
||||
* The Open Group Base Specifications Issue 8 - IEEE Std 1003.1-2024
|
||||
* https://pubs.opengroup.org/onlinepubs/9799919799/functions/getentropy.html
|
||||
*
|
||||
* NOTE: `getentropy`(3) on Linux is implemented using `getrandom`(2),
|
||||
* prefer the latter over this if both are defined.
|
||||
*/
|
||||
#ifndef GETENTROPY_MAX
|
||||
# define GETENTROPY_MAX 256
|
||||
#endif
|
||||
static int
|
||||
fill_random_bytes_syscall(void *seed, size_t size, int need_secure)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)seed;
|
||||
while (size) {
|
||||
size_t len = size < GETENTROPY_MAX ? size : GETENTROPY_MAX;
|
||||
if (getentropy(p, len) != 0) {
|
||||
return -1;
|
||||
}
|
||||
p += len;
|
||||
size -= len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
# define fill_random_bytes_syscall(seed, size, need_secure) -1
|
||||
#endif
|
||||
@ -675,6 +692,7 @@ ruby_fill_random_bytes(void *seed, size_t size, int need_secure)
|
||||
{
|
||||
int ret = fill_random_bytes_syscall(seed, size, need_secure);
|
||||
if (ret == 0) return ret;
|
||||
if (fill_random_bytes_lib(seed, size) == 0) return 0;
|
||||
return fill_random_bytes_urandom(seed, size);
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
|
||||
#define RUBY_VERSION_TEENY 4
|
||||
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
|
||||
#define RUBY_PATCHLEVEL 46
|
||||
#define RUBY_PATCHLEVEL 47
|
||||
|
||||
#include "ruby/version.h"
|
||||
#include "ruby/internal/abi.h"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user