From: Lennart Poettering Date: Thu, 11 Jun 2020 07:53:29 +0000 (+0200) Subject: random-util: add common helper random_write_entropy() for crediting entropy to the... X-Git-Tag: v246-rc1~71^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4dd055f907eda30b95c9cdd0b822120bbf646ecf;p=thirdparty%2Fsystemd.git random-util: add common helper random_write_entropy() for crediting entropy to the kernel's pool --- diff --git a/src/basic/random-util.c b/src/basic/random-util.c index 73cc7272db4..4a30c4d359c 100644 --- a/src/basic/random-util.c +++ b/src/basic/random-util.c @@ -7,11 +7,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #if HAVE_SYS_AUXV_H @@ -438,3 +440,36 @@ size_t random_pool_size(void) { /* Use the minimum as default, if we can't retrieve the correct value */ return RANDOM_POOL_SIZE_MIN; } + +int random_write_entropy(int fd, const void *seed, size_t size, bool credit) { + int r; + + assert(fd >= 0); + assert(seed && size > 0); + + if (credit) { + _cleanup_free_ struct rand_pool_info *info = NULL; + + /* The kernel API only accepts "int" as entropy count (which is in bits), let's avoid any + * chance for confusion here. */ + if (size > INT_MAX / 8) + return -EOVERFLOW; + + info = malloc(offsetof(struct rand_pool_info, buf) + size); + if (!info) + return -ENOMEM; + + info->entropy_count = size * 8; + info->buf_size = size; + memcpy(info->buf, seed, size); + + if (ioctl(fd, RNDADDENTROPY, info) < 0) + return -errno; + } else { + r = loop_write(fd, seed, size, false); + if (r < 0) + return r; + } + + return 0; +} diff --git a/src/basic/random-util.h b/src/basic/random-util.h index d8e067d96e8..7824ffacebb 100644 --- a/src/basic/random-util.h +++ b/src/basic/random-util.h @@ -38,3 +38,5 @@ int rdrand(unsigned long *ret); #define RANDOM_POOL_SIZE_MAX (10U*1024U*1024U) size_t random_pool_size(void); + +int random_write_entropy(int fd, const void *seed, size_t size, bool credit); diff --git a/src/core/efi-random.c b/src/core/efi-random.c index c4d25d68e42..b6609e63e54 100644 --- a/src/core/efi-random.c +++ b/src/core/efi-random.c @@ -1,8 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #include -#include -#include #include #include "alloc-util.h" @@ -11,6 +9,7 @@ #include "efivars.h" #include "fd-util.h" #include "fs-util.h" +#include "random-util.h" #include "strv.h" /* If a random seed was passed by the boot loader in the LoaderRandomSeed EFI variable, let's credit it to @@ -43,7 +42,6 @@ static void lock_down_efi_variables(void) { } int efi_take_random_seed(void) { - _cleanup_free_ struct rand_pool_info *info = NULL; _cleanup_free_ void *value = NULL; _cleanup_close_ int random_fd = -1; size_t size; @@ -79,11 +77,6 @@ int efi_take_random_seed(void) { if (size == 0) return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Random seed passed from boot loader has zero size? Ignoring."); - /* The kernel API only accepts "int" as entropy count (which is in bits), let's avoid any chance for - * confusion here. */ - if (size > INT_MAX / 8) - size = INT_MAX / 8; - random_fd = open("/dev/urandom", O_WRONLY|O_CLOEXEC|O_NOCTTY); if (random_fd < 0) return log_warning_errno(errno, "Failed to open /dev/urandom for writing, ignoring: %m"); @@ -94,15 +87,8 @@ int efi_take_random_seed(void) { if (r < 0) return log_warning_errno(r, "Unable to mark EFI random seed as used, not using it: %m"); - info = malloc(offsetof(struct rand_pool_info, buf) + size); - if (!info) - return log_oom(); - - info->entropy_count = size * 8; - info->buf_size = size; - memcpy(info->buf, value, size); - - if (ioctl(random_fd, RNDADDENTROPY, info) < 0) + r = random_write_entropy(random_fd, value, size, true); + if (r < 0) return log_warning_errno(errno, "Failed to credit entropy, ignoring: %m"); log_info("Successfully credited entropy passed from boot loader."); diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c index 89452c8e152..63ad977514d 100644 --- a/src/random-seed/random-seed.c +++ b/src/random-seed/random-seed.c @@ -236,24 +236,10 @@ static int run(int argc, char *argv[]) { } } - if (IN_SET(lets_credit, CREDIT_ENTROPY_YES_PLEASE, CREDIT_ENTROPY_YES_FORCED)) { - _cleanup_free_ struct rand_pool_info *info = NULL; - - info = malloc(offsetof(struct rand_pool_info, buf) + k); - if (!info) - return log_oom(); - - info->entropy_count = k * 8; - info->buf_size = k; - memcpy(info->buf, buf, k); - - if (ioctl(random_fd, RNDADDENTROPY, info) < 0) - return log_warning_errno(errno, "Failed to credit entropy, ignoring: %m"); - } else { - r = loop_write(random_fd, buf, (size_t) k, false); - if (r < 0) - log_error_errno(r, "Failed to write seed to /dev/urandom: %m"); - } + r = random_write_entropy(random_fd, buf, k, + IN_SET(lets_credit, CREDIT_ENTROPY_YES_PLEASE, CREDIT_ENTROPY_YES_FORCED)); + if (r < 0) + log_error_errno(r, "Failed to write seed to /dev/urandom: %m"); } }