]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
random-util: our baseline includes getrandom() (v3.17) now 35816/head
authorMike Yuan <me@yhndnzj.com>
Thu, 2 Jan 2025 19:03:33 +0000 (20:03 +0100)
committerMike Yuan <me@yhndnzj.com>
Thu, 2 Jan 2025 19:40:45 +0000 (20:40 +0100)
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
meson.build
src/basic/missing_random.h
src/basic/missing_syscall.h
src/basic/random-util.c
src/random-seed/random-seed.c

diff --git a/README b/README
index 330554eb47aa01f8d7a03a3e21c449ee633570f4..4dabdaee06263fd9a44e7e3a7ad47c19220710d7 100644 (file)
--- 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
index d9fb8fb61304d032b5ac345b36044d5625dfed9b..538e776ab48cd06fdc8e12cd3cdf64d561307e37 100644 (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')
index 0f8a5be0a233abdf8b5e0d0b0f3d77ec834d145a..5f40c4e58c681f19f68c6c448c9fb0a0c6d6e919 100644 (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>
index 00aeda726a65bb6646216fe23161078d367240f0..8aba8584acec677408878a3dff32ef4638b9ae39 100644 (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
index 0b767a85009c9793af54d44815d68f8a265c33bb..02713859f02fe42441fb4e6ffb9197d56c4daf32 100644 (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)
+                if (l < 0)
+                        return -errno;
+                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;
+                if ((size_t) l == n)
+                        return 0; /* Done reading, success. */
 
-                ready_fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY);
-                if (ready_fd < 0)
-                        return -errno;
-                r = fd_wait_for_event(ready_fd, POLLIN, USEC_INFINITY);
-                if (r < 0)
-                        return r;
-                seen_initialized = true;
+                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)
-                return -errno;
-        return loop_read_exact(fd, p, n, false);
 }
 
 int crypto_random_bytes_allocate_iovec(size_t n, struct iovec *ret) {
index bad18ada3b6e731a04f70f6f16c420b6e90841f1..4d458646a031b4e47738f16d3b144d805962a282 100644 (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>