From c439bd25ca87d59beeab26de52dbdb13c9209421 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Thu, 2 Jan 2025 20:03:33 +0100 Subject: [PATCH] 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. --- README | 4 +- meson.build | 10 +--- src/basic/missing_random.h | 2 +- src/basic/missing_syscall.h | 5 -- src/basic/random-util.c | 87 ++++++++++++----------------------- src/random-seed/random-seed.c | 3 -- 6 files changed, 33 insertions(+), 78 deletions(-) diff --git a/README b/README index 330554eb47a..4dabdaee062 100644 --- a/README +++ b/README @@ -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 diff --git a/meson.build b/meson.build index d9fb8fb6130..538e776ab48 100644 --- a/meson.build +++ b/meson.build @@ -676,21 +676,13 @@ foreach ident : [ ['getdents64', '''#include '''], ['pidfd_spawn', '''#include '''], ['strerrorname_np', '''#include '''], + ['getrandom', '''#include '''], ] 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 ''', args : '-D_GNU_SOURCE') - conf.set10('USE_SYS_RANDOM_H', true) - conf.set10('HAVE_GETRANDOM', true) -else - have = cc.has_function('getrandom', prefix : '''#include ''') - conf.set10('USE_SYS_RANDOM_H', false) - conf.set10('HAVE_GETRANDOM', have) -endif - ##################################################################### sh = find_program('sh') diff --git a/src/basic/missing_random.h b/src/basic/missing_random.h index 0f8a5be0a23..5f40c4e58c6 100644 --- a/src/basic/missing_random.h +++ b/src/basic/missing_random.h @@ -3,7 +3,7 @@ #include "macro.h" -#if USE_SYS_RANDOM_H +#if HAVE_GETRANDOM # include #else # include diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h index 00aeda726a6..8aba8584ace 100644 --- a/src/basic/missing_syscall.h +++ b/src/basic/missing_syscall.h @@ -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 diff --git a/src/basic/random-util.c b/src/basic/random-util.c index 0b767a85009..02713859f02 100644 --- a/src/basic/random-util.c +++ b/src/basic/random-util.c @@ -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) { diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c index bad18ada3b6..4d458646a03 100644 --- a/src/random-seed/random-seed.c +++ b/src/random-seed/random-seed.c @@ -5,9 +5,6 @@ #include #include #include -#if USE_SYS_RANDOM_H -# include -#endif #include #include #include