1
0
mirror of https://github.com/systemd/systemd synced 2025-10-06 00:13:24 +02:00

random-util: our baseline includes getrandom() (v3.17) now

Plus, linux/random.h never defined getrandom(), hence remove
the custom machinery for sys/random.h vs linux/random.h
in favor of single HAVE_GETRANDOM.
This commit is contained in:
Mike Yuan
2025-01-02 20:03:33 +01:00
parent 2627cd1343
commit c439bd25ca
6 changed files with 33 additions and 78 deletions

4
README
View File

@@ -51,8 +51,8 @@ REQUIREMENTS:
≥ 6.9 for pidfs
⛔ Kernel versions below 4.3 ("minimum baseline") are not supported at
all, and are missing required functionality (e.g. CLOCK_BOOTTIME
support for timerfd_create(), ambient capabilities, or memfd_create()).
all, and are missing required functionality (e.g. CLOCK_BOOTTIME support
for timerfd_create(), getrandom(), ambient capabilities, or memfd_create()).
⚠️ Kernel versions below 5.4 ("recommended baseline") have significant
gaps in functionality and are not recommended for use with this version

View File

@@ -676,21 +676,13 @@ foreach ident : [
['getdents64', '''#include <dirent.h>'''],
['pidfd_spawn', '''#include <spawn.h>'''],
['strerrorname_np', '''#include <string.h>'''],
['getrandom', '''#include <sys/random.h>'''],
]
have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE')
conf.set10('HAVE_' + ident[0].to_upper(), have)
endforeach
if cc.has_function('getrandom', prefix : '''#include <sys/random.h>''', args : '-D_GNU_SOURCE')
conf.set10('USE_SYS_RANDOM_H', true)
conf.set10('HAVE_GETRANDOM', true)
else
have = cc.has_function('getrandom', prefix : '''#include <linux/random.h>''')
conf.set10('USE_SYS_RANDOM_H', false)
conf.set10('HAVE_GETRANDOM', have)
endif
#####################################################################
sh = find_program('sh')

View File

@@ -3,7 +3,7 @@
#include "macro.h"
#if USE_SYS_RANDOM_H
#if HAVE_GETRANDOM
# include <sys/random.h>
#else
# include <linux/random.h>

View File

@@ -91,12 +91,7 @@ static inline int missing_memfd_create(const char *name, unsigned int flags) {
#if !HAVE_GETRANDOM
/* glibc says getrandom() returns ssize_t */
static inline ssize_t missing_getrandom(void *buffer, size_t count, unsigned flags) {
# ifdef __NR_getrandom
return syscall(__NR_getrandom, buffer, count, flags);
# else
errno = ENOSYS;
return -1;
# endif
}
# define getrandom missing_getrandom

View File

@@ -71,8 +71,9 @@ static void fallback_random_bytes(void *p, size_t n) {
}
void random_bytes(void *p, size_t n) {
static bool have_getrandom = true, have_grndinsecure = true;
_cleanup_close_ int fd = -EBADF;
static bool have_grndinsecure = true;
assert(p || n == 0);
if (n == 0)
return;
@@ -80,32 +81,26 @@ void random_bytes(void *p, size_t n) {
for (;;) {
ssize_t l;
if (!have_getrandom)
break;
l = getrandom(p, n, have_grndinsecure ? GRND_INSECURE : GRND_NONBLOCK);
if (l > 0) {
if ((size_t) l == n)
return; /* Done reading, success. */
p = (uint8_t *) p + l;
n -= l;
continue; /* Interrupted by a signal; keep going. */
} else if (l == 0)
break; /* Weird, so fallback to /dev/urandom. */
else if (ERRNO_IS_NOT_SUPPORTED(errno)) {
have_getrandom = false;
break; /* No syscall, so fallback to /dev/urandom. */
} else if (errno == EINVAL && have_grndinsecure) {
if (l < 0 && errno == EINVAL && have_grndinsecure) {
/* No GRND_INSECURE; fallback to GRND_NONBLOCK. */
have_grndinsecure = false;
continue; /* No GRND_INSECURE; fallback to GRND_NONBLOCK. */
} else if (errno == EAGAIN && !have_grndinsecure)
break; /* Will block, but no GRND_INSECURE, so fallback to /dev/urandom. */
continue;
}
if (l <= 0)
break; /* Will block (with GRND_NONBLOCK), or unexpected error. Give up and fallback
to /dev/urandom. */
break; /* Unexpected, so just give up and fallback to /dev/urandom. */
if ((size_t) l == n)
return; /* Done reading, success. */
p = (uint8_t *) p + l;
n -= l;
/* Interrupted by a signal; keep going. */
}
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (fd >= 0 && loop_read_exact(fd, p, n, false) == 0)
_cleanup_close_ int fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (fd >= 0 && loop_read_exact(fd, p, n, false) >= 0)
return;
/* This is a terrible fallback. Oh well. */
@@ -113,8 +108,7 @@ void random_bytes(void *p, size_t n) {
}
int crypto_random_bytes(void *p, size_t n) {
static bool have_getrandom = true, seen_initialized = false;
_cleanup_close_ int fd = -EBADF;
assert(p || n == 0);
if (n == 0)
return 0;
@@ -122,42 +116,19 @@ int crypto_random_bytes(void *p, size_t n) {
for (;;) {
ssize_t l;
if (!have_getrandom)
break;
l = getrandom(p, n, 0);
if (l > 0) {
if ((size_t) l == n)
return 0; /* Done reading, success. */
p = (uint8_t *) p + l;
n -= l;
continue; /* Interrupted by a signal; keep going. */
} else if (l == 0)
return -EIO; /* Weird, should never happen. */
else if (ERRNO_IS_NOT_SUPPORTED(errno)) {
have_getrandom = false;
break; /* No syscall, so fallback to /dev/urandom. */
}
return -errno;
}
if (!seen_initialized) {
_cleanup_close_ int ready_fd = -EBADF;
int r;
ready_fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (ready_fd < 0)
if (l < 0)
return -errno;
r = fd_wait_for_event(ready_fd, POLLIN, USEC_INFINITY);
if (r < 0)
return r;
seen_initialized = true;
}
if (l == 0)
return -EIO; /* Weird, should never happen. */
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
return -errno;
return loop_read_exact(fd, p, n, false);
if ((size_t) l == n)
return 0; /* Done reading, success. */
p = (uint8_t *) p + l;
n -= l;
/* Interrupted by a signal; keep going. */
}
}
int crypto_random_bytes_allocate_iovec(size_t n, struct iovec *ret) {

View File

@@ -5,9 +5,6 @@
#include <getopt.h>
#include <linux/random.h>
#include <sys/ioctl.h>
#if USE_SYS_RANDOM_H
# include <sys/random.h>
#endif
#include <sys/stat.h>
#include <sys/xattr.h>
#include <unistd.h>