You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
systemd/SOURCES/0711-bootctl-when-updating-...

91 lines
3.4 KiB

From a698bb3a2dd4fec2302e0aebef4d8359d8d4cf40 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 20 Dec 2022 11:48:21 +0100
Subject: [PATCH] bootctl: when updating EFI random seed file, hash old seed
with new one
Let's not regress in entropy in any case.
This does what f913c784ad4c93894fd6cb2590738113dff5a694 also does.
(cherry picked from commit 114172fbe75b247883dd873cafb9209e4a2bd778)
Related: RHEL-16952
---
src/boot/bootctl.c | 36 +++++++++++++++++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index 5edcf0fc32..fe8d7e83a1 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -43,6 +43,7 @@
#include "pretty-print.h"
#include "random-util.h"
#include "rm-rf.h"
+#include "sha256.h"
#include "stat-util.h"
#include "stdio-util.h"
#include "string-table.h"
@@ -1987,11 +1988,15 @@ static int install_random_seed(const char *esp) {
_cleanup_close_ int esp_fd = -EBADF, loader_dir_fd = -EBADF, fd = -EBADF;
_cleanup_free_ char *tmp = NULL;
uint8_t buffer[RANDOM_EFI_SEED_SIZE];
+ struct sha256_ctx hash_state;
size_t token_size;
+ bool refreshed;
int r;
assert(esp);
+ assert_cc(RANDOM_EFI_SEED_SIZE == SHA256_DIGEST_SIZE);
+
esp_fd = open(esp, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
if (esp_fd < 0)
return log_error_errno(errno, "Failed to open ESP directory '%s': %m", esp);
@@ -2004,6 +2009,35 @@ static int install_random_seed(const char *esp) {
if (r < 0)
return log_error_errno(r, "Failed to acquire random seed: %m");
+ sha256_init_ctx(&hash_state);
+ sha256_process_bytes(&(const size_t) { sizeof(buffer) }, sizeof(size_t), &hash_state);
+ sha256_process_bytes(buffer, sizeof(buffer), &hash_state);
+
+ fd = openat(loader_dir_fd, "random-seed", O_NOFOLLOW|O_CLOEXEC|O_RDONLY|O_NOCTTY);
+ if (fd < 0) {
+ if (errno != ENOENT)
+ return log_error_errno(errno, "Failed to open old random seed file: %m");
+
+ sha256_process_bytes(&(const ssize_t) { 0 }, sizeof(ssize_t), &hash_state);
+ refreshed = false;
+ } else {
+ ssize_t n;
+
+ /* Hash the old seed in so that we never regress in entropy. */
+
+ n = read(fd, buffer, sizeof(buffer));
+ if (n < 0)
+ return log_error_errno(errno, "Failed to read old random seed file: %m");
+
+ sha256_process_bytes(&n, sizeof(n), &hash_state);
+ sha256_process_bytes(buffer, n, &hash_state);
+
+ fd = safe_close(fd);
+ refreshed = n > 0;
+ }
+
+ sha256_finish_ctx(&hash_state, buffer);
+
if (tempfn_random("random-seed", "bootctl", &tmp) < 0)
return log_oom();
@@ -2032,7 +2066,7 @@ static int install_random_seed(const char *esp) {
if (syncfs(fd) < 0)
return log_error_errno(errno, "Failed to sync ESP file system: %m");
- log_info("Random seed file %s/loader/random-seed successfully written (%zu bytes).", esp, sizeof(buffer));
+ log_info("Random seed file %s/loader/random-seed successfully %s (%zu bytes).", esp, refreshed ? "refreshed" : "written", sizeof(buffer));
if (!arg_touch_variables)
return 0;