systemd-252-31

Resolves: RHEL-16952
This commit is contained in:
Jan Macku 2024-03-15 14:22:25 +01:00
parent fe8745ee78
commit a83ff382a5
9 changed files with 1169 additions and 1 deletions

View File

@ -0,0 +1,120 @@
From e12d41f584e33c0183a47d6c7211ccbf23f3e6a4 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 19 Dec 2022 22:26:30 +0100
Subject: [PATCH] bootctl: rework random seed logic to use open_mkdir_at() and
openat()
This doesn't really fix anything, but in general we should put stronger
emphasis on operating via dir fds rather than paths more (in particular
when writing files as opposed to consuming them).
No real change in behaviour.
(cherry picked from commit 6b97b267bf990b2ec553efae229b7996dc262996)
Related: RHEL-16952
---
src/boot/bootctl.c | 57 +++++++++++++++++++++++-----------------------
1 file changed, 29 insertions(+), 28 deletions(-)
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index c994be272b..9bb99eeec1 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -31,6 +31,7 @@
#include "fileio.h"
#include "find-esp.h"
#include "fs-util.h"
+#include "io-util.h"
#include "glyph-util.h"
#include "main-func.h"
#include "mkdir.h"
@@ -1983,53 +1984,47 @@ static int verb_list(int argc, char *argv[], void *userdata) {
}
static int install_random_seed(const char *esp) {
- _cleanup_(unlink_and_freep) char *tmp = NULL;
+ _cleanup_close_ int esp_fd = -EBADF, loader_dir_fd = -EBADF, fd = -EBADF;
+ _cleanup_free_ char *tmp = NULL;
uint8_t buffer[RANDOM_EFI_SEED_SIZE];
- _cleanup_free_ char *path = NULL;
- _cleanup_close_ int fd = -1;
size_t token_size;
- ssize_t n;
int r;
assert(esp);
- path = path_join(esp, "/loader/random-seed");
- if (!path)
- return log_oom();
+ 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);
+
+ loader_dir_fd = open_mkdir_at(esp_fd, "loader", O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOFOLLOW, 0775);
+ if (loader_dir_fd < 0)
+ return log_error_errno(loader_dir_fd, "Failed to open loader directory '%s/loader': %m", esp);
r = crypto_random_bytes(buffer, sizeof(buffer));
if (r < 0)
return log_error_errno(r, "Failed to acquire random seed: %m");
- /* Normally create_subdirs() should already have created everything we need, but in case "bootctl
- * random-seed" is called we want to just create the minimum we need for it, and not the full
- * list. */
- r = mkdir_parents(path, 0755);
- if (r < 0)
- return log_error_errno(r, "Failed to create parent directory for %s: %m", path);
-
- r = tempfn_random(path, "bootctl", &tmp);
- if (r < 0)
+ if (tempfn_random("random-seed", "bootctl", &tmp) < 0)
return log_oom();
- fd = open(tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|O_WRONLY|O_CLOEXEC, 0600);
- if (fd < 0) {
- tmp = mfree(tmp);
+ fd = openat(loader_dir_fd, tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|O_WRONLY|O_CLOEXEC, 0600);
+ if (fd < 0)
return log_error_errno(fd, "Failed to open random seed file for writing: %m");
- }
- n = write(fd, buffer, sizeof(buffer));
- if (n < 0)
- return log_error_errno(errno, "Failed to write random seed file: %m");
- if ((size_t) n != sizeof(buffer))
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short write while writing random seed file.");
+ r = loop_write(fd, buffer, sizeof(buffer), /* do_poll= */ false);
+ if (r < 0) {
+ log_error_errno(r, "Failed to write random seed file: %m");
+ goto fail;
+ }
- if (rename(tmp, path) < 0)
- return log_error_errno(errno, "Failed to move random seed file into place: %m");
+ if (renameat(loader_dir_fd, tmp, loader_dir_fd, "random-seed") < 0) {
+ r = log_error_errno(errno, "Failed to move random seed file into place: %m");
+ goto fail;
+ }
tmp = mfree(tmp);
- log_info("Random seed file %s successfully written (%zu bytes).", path, sizeof(buffer));
+ log_info("Random seed file %s/loader/random-seed successfully written (%zu bytes).", esp, sizeof(buffer));
if (!arg_touch_variables)
return 0;
@@ -2092,6 +2087,12 @@ static int install_random_seed(const char *esp) {
}
return 0;
+
+fail:
+ if (tmp)
+ (void) unlinkat(loader_dir_fd, tmp, 0);
+
+ return r;
}
static int sync_everything(void) {

View File

@ -0,0 +1,51 @@
From 30aa0b51b3edba2cda99abf32e7965afb4ea311c Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 20 Dec 2022 11:15:51 +0100
Subject: [PATCH] bootctl: properly sync fs before/after moving random seed
file into place
Let's do a careful, focussed sync at the right places instead of a
blanket sync at the end. After all we want to run this on every boot
soon.
(cherry picked from commit 60315d59534fe59aacae26e2c497359a409af0b6)
Related: RHEL-16952
---
src/boot/bootctl.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index 9bb99eeec1..5edcf0fc32 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -2017,6 +2017,11 @@ static int install_random_seed(const char *esp) {
goto fail;
}
+ if (fsync(fd) < 0 || fsync(loader_dir_fd) < 0) {
+ r = log_error_errno(errno, "Failed to sync random seed file: %m");
+ goto fail;
+ }
+
if (renameat(loader_dir_fd, tmp, loader_dir_fd, "random-seed") < 0) {
r = log_error_errno(errno, "Failed to move random seed file into place: %m");
goto fail;
@@ -2024,6 +2029,9 @@ static int install_random_seed(const char *esp) {
tmp = mfree(tmp);
+ 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));
if (!arg_touch_variables)
@@ -2468,7 +2476,6 @@ static int verb_random_seed(int argc, char *argv[], void *userdata) {
if (r < 0)
return r;
- (void) sync_everything();
return 0;
}

View File

@ -0,0 +1,90 @@
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;

View File

@ -0,0 +1,101 @@
From 7b9e71d4f8d01557da700f2da11870f6246abdf2 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 20 Dec 2022 11:53:37 +0100
Subject: [PATCH] sha256: add helper than hashes a buffer *and* its size
We use this pattern all the time in order to thward extension attacks,
add a helper to make it shorter.
(cherry picked from commit a16c65f3c4c93e24eda9cf7f14d5da4062c6ca10)
Related: RHEL-16952
---
src/boot/bootctl.c | 6 ++----
src/fundamental/sha256.h | 5 +++++
src/random-seed/random-seed.c | 12 ++++--------
3 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index fe8d7e83a1..3e9a89a759 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -2010,8 +2010,7 @@ static int install_random_seed(const char *esp) {
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);
+ sha256_process_bytes_and_size(buffer, sizeof(buffer), &hash_state);
fd = openat(loader_dir_fd, "random-seed", O_NOFOLLOW|O_CLOEXEC|O_RDONLY|O_NOCTTY);
if (fd < 0) {
@@ -2029,8 +2028,7 @@ static int install_random_seed(const char *esp) {
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);
+ sha256_process_bytes_and_size(buffer, n, &hash_state);
fd = safe_close(fd);
refreshed = n > 0;
diff --git a/src/fundamental/sha256.h b/src/fundamental/sha256.h
index 31790c2ebd..2857900c80 100644
--- a/src/fundamental/sha256.h
+++ b/src/fundamental/sha256.h
@@ -28,6 +28,11 @@ void sha256_init_ctx(struct sha256_ctx *ctx);
uint8_t *sha256_finish_ctx(struct sha256_ctx *ctx, uint8_t resbuf[static SHA256_DIGEST_SIZE]);
void sha256_process_bytes(const void *buffer, size_t len, struct sha256_ctx *ctx);
+static inline void sha256_process_bytes_and_size(const void *buffer, size_t len, struct sha256_ctx *ctx) {
+ sha256_process_bytes(&len, sizeof(len), ctx);
+ sha256_process_bytes(buffer, len, ctx);
+}
+
uint8_t* sha256_direct(const void *buffer, size_t sz, uint8_t result[static SHA256_DIGEST_SIZE]);
#define SHA256_DIRECT(buffer, sz) sha256_direct(buffer, sz, (uint8_t[SHA256_DIGEST_SIZE]) {})
diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c
index ab1f942289..3bb78200c9 100644
--- a/src/random-seed/random-seed.c
+++ b/src/random-seed/random-seed.c
@@ -195,8 +195,7 @@ static int load_seed_file(
return log_oom();
sha256_init_ctx(hash_state);
- sha256_process_bytes(&k, sizeof(k), hash_state); /* Hash length to distinguish from new seed. */
- sha256_process_bytes(buf, k, hash_state);
+ sha256_process_bytes_and_size(buf, k, hash_state); /* Hash with length to distinguish from new seed. */
*ret_hash_state = hash_state;
}
@@ -289,8 +288,7 @@ static int save_seed_file(
if (hash_state) {
uint8_t hash[SHA256_DIGEST_SIZE];
- sha256_process_bytes(&k, sizeof(k), hash_state); /* Hash length to distinguish from old seed. */
- sha256_process_bytes(buf, k, hash_state);
+ sha256_process_bytes_and_size(buf, k, hash_state); /* Hash with length to distinguish from old seed. */
sha256_finish_ctx(hash_state, hash);
l = MIN((size_t)k, sizeof(hash));
memcpy((uint8_t *)buf + k - l, hash, l);
@@ -371,8 +369,7 @@ static int refresh_boot_seed(void) {
/* Hash the old seed in so that we never regress in entropy. */
sha256_init_ctx(&hash_state);
- sha256_process_bytes(&n, sizeof(n), &hash_state);
- sha256_process_bytes(seed_file_bytes, n, &hash_state);
+ sha256_process_bytes_and_size(seed_file_bytes, n, &hash_state);
/* We're doing this opportunistically, so if the seeding dance before didn't manage to initialize the
* RNG, there's no point in doing it here. Secondly, getrandom(GRND_NONBLOCK) has been around longer
@@ -393,8 +390,7 @@ static int refresh_boot_seed(void) {
assert(n == sizeof(buffer));
/* Hash the new seed into the state containing the old one to generate our final seed. */
- sha256_process_bytes(&n, sizeof(n), &hash_state);
- sha256_process_bytes(buffer, n, &hash_state);
+ sha256_process_bytes_and_size(buffer, n, &hash_state);
sha256_finish_ctx(&hash_state, buffer);
if (lseek(seed_fd, 0, SEEK_SET) < 0)

View File

@ -0,0 +1,191 @@
From 5c3c932aeef27dcc0b4cb91aeb7e52974add6998 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 20 Dec 2022 16:18:11 +0100
Subject: [PATCH] random-seed: don't refresh EFI random seed from random-seed.c
anymore
The ESP is simply not mounted early enough for this. We want that the
regular random seed handling runs as early as we possibly could, but we
don't want to delay this until the ESP is actually mounted.
Hence, let's remove this from random-seed.c here. A follow-up commit
will then add this back in, in a separate service which just calls
"bootctl random-seed".
Effectively reverts: f913c784ad4c93894fd6cb2590738113dff5a694
Fixes: #25769
(cherry picked from commit 29d487adb4ce70cc87a09ce2003d29789b2b4c3f)
Related: RHEL-16952
---
src/random-seed/random-seed.c | 111 +---------------------------------
1 file changed, 2 insertions(+), 109 deletions(-)
diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c
index 3bb78200c9..79544c1027 100644
--- a/src/random-seed/random-seed.c
+++ b/src/random-seed/random-seed.c
@@ -16,10 +16,7 @@
#include "alloc-util.h"
#include "build.h"
-#include "chase-symlinks.h"
-#include "efi-loader.h"
#include "fd-util.h"
-#include "find-esp.h"
#include "fs-util.h"
#include "io-util.h"
#include "log.h"
@@ -27,17 +24,13 @@
#include "missing_random.h"
#include "missing_syscall.h"
#include "mkdir.h"
-#include "parse-argument.h"
#include "parse-util.h"
-#include "path-util.h"
#include "pretty-print.h"
#include "random-util.h"
#include "string-table.h"
#include "string-util.h"
-#include "strv.h"
#include "sync-util.h"
#include "sha256.h"
-#include "terminal-util.h"
#include "util.h"
#include "xattr-util.h"
@@ -314,100 +307,6 @@ static int save_seed_file(
return 0;
}
-static int refresh_boot_seed(void) {
- uint8_t buffer[RANDOM_EFI_SEED_SIZE];
- struct sha256_ctx hash_state;
- _cleanup_free_ void *seed_file_bytes = NULL;
- _cleanup_free_ char *esp_path = NULL;
- _cleanup_close_ int seed_fd = -1, dir_fd = -1;
- size_t len;
- ssize_t n;
- int r;
-
- assert_cc(RANDOM_EFI_SEED_SIZE == SHA256_DIGEST_SIZE);
-
- r = find_esp_and_warn(NULL, NULL, /* unprivileged_mode= */ false, &esp_path,
- NULL, NULL, NULL, NULL, NULL);
- if (r < 0) {
- if (r == -ENOKEY) {
- log_debug_errno(r, "Couldn't find any ESP, so not updating ESP random seed.");
- return 0;
- }
- return r; /* find_esp_and_warn() already logged */
- }
-
- r = chase_symlinks("/loader", esp_path, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, NULL, &dir_fd);
- if (r < 0) {
- if (r == -ENOENT) {
- log_debug_errno(r, "Couldn't find ESP loader directory, so not updating ESP random seed.");
- return 0;
- }
- return log_error_errno(r, "Failed to open ESP loader directory: %m");
- }
- seed_fd = openat(dir_fd, "random-seed", O_NOFOLLOW|O_RDWR|O_CLOEXEC|O_NOCTTY);
- if (seed_fd < 0 && errno == ENOENT) {
- uint64_t features;
- r = efi_loader_get_features(&features);
- if (r == 0 && FLAGS_SET(features, EFI_LOADER_FEATURE_RANDOM_SEED))
- seed_fd = openat(dir_fd, "random-seed", O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC|O_NOCTTY, 0600);
- else {
- log_debug_errno(seed_fd, "Couldn't find ESP random seed, and not booted with systemd-boot, so not updating ESP random seed.");
- return 0;
- }
- }
- if (seed_fd < 0)
- return log_error_errno(errno, "Failed to open EFI seed path: %m");
- r = random_seed_size(seed_fd, &len);
- if (r < 0)
- return log_error_errno(r, "Failed to determine EFI seed path length: %m");
- seed_file_bytes = malloc(len);
- if (!seed_file_bytes)
- return log_oom();
- n = loop_read(seed_fd, seed_file_bytes, len, false);
- if (n < 0)
- return log_error_errno(n, "Failed to read EFI seed file: %m");
-
- /* Hash the old seed in so that we never regress in entropy. */
- sha256_init_ctx(&hash_state);
- sha256_process_bytes_and_size(seed_file_bytes, n, &hash_state);
-
- /* We're doing this opportunistically, so if the seeding dance before didn't manage to initialize the
- * RNG, there's no point in doing it here. Secondly, getrandom(GRND_NONBLOCK) has been around longer
- * than EFI seeding anyway, so there's no point in having non-getrandom() fallbacks here. So if this
- * fails, just return early to cut our losses. */
- n = getrandom(buffer, sizeof(buffer), GRND_NONBLOCK);
- if (n < 0) {
- if (errno == EAGAIN) {
- log_debug_errno(errno, "Random pool not initialized yet, so skipping EFI seed update");
- return 0;
- }
- if (errno == ENOSYS) {
- log_debug_errno(errno, "getrandom() not available, so skipping EFI seed update");
- return 0;
- }
- return log_error_errno(errno, "Failed to generate random bytes for EFI seed: %m");
- }
- assert(n == sizeof(buffer));
-
- /* Hash the new seed into the state containing the old one to generate our final seed. */
- sha256_process_bytes_and_size(buffer, n, &hash_state);
- sha256_finish_ctx(&hash_state, buffer);
-
- if (lseek(seed_fd, 0, SEEK_SET) < 0)
- return log_error_errno(errno, "Failed to seek to beginning of EFI seed file: %m");
- r = loop_write(seed_fd, buffer, sizeof(buffer), false);
- if (r < 0)
- return log_error_errno(r, "Failed to write new EFI seed file: %m");
- if (ftruncate(seed_fd, sizeof(buffer)) < 0)
- return log_error_errno(errno, "Failed to truncate EFI seed file: %m");
- r = fsync_full(seed_fd);
- if (r < 0)
- return log_error_errno(r, "Failed to fsync EFI seed file: %m");
-
- log_debug("Updated random seed in ESP");
- return 0;
-}
-
static int help(int argc, char *argv[], void *userdata) {
_cleanup_free_ char *link = NULL;
int r;
@@ -525,10 +424,7 @@ static int run(int argc, char *argv[]) {
log_full_errno(level, open_rw_error, "Failed to open " RANDOM_SEED " for writing: %m");
log_full_errno(level, errno, "Failed to open " RANDOM_SEED " for reading: %m");
- r = -errno;
-
- (void) refresh_boot_seed();
- return missing ? 0 : r;
+ return missing ? 0 : -errno;
}
} else
write_seed_file = true;
@@ -538,7 +434,6 @@ static int run(int argc, char *argv[]) {
break;
case ACTION_SAVE:
- (void) refresh_boot_seed();
seed_fd = open(RANDOM_SEED, O_WRONLY|O_CLOEXEC|O_NOCTTY|O_CREAT, 0600);
if (seed_fd < 0)
return log_error_errno(errno, "Failed to open " RANDOM_SEED ": %m");
@@ -556,11 +451,9 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return r;
- if (read_seed_file) {
+ if (read_seed_file)
r = load_seed_file(seed_fd, random_fd, seed_size,
write_seed_file ? &hash_state : NULL);
- (void) refresh_boot_seed();
- }
if (r >= 0 && write_seed_file)
r = save_seed_file(seed_fd, random_fd, seed_size, synchronous, hash_state);

View File

@ -0,0 +1,34 @@
From 825d1d4535a7aafd7549bc7a5de7d72b5ec2cdbd Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 20 Dec 2022 16:34:36 +0100
Subject: [PATCH] bootctl: downgrade graceful messages to LOG_NOTICE
(cherry picked from commit 5019b0cb15d788e5e1f3c15eb7cdca6ee18a847c)
Related: RHEL-16952
---
src/boot/bootctl.c | 4 ++--
...-system-token.service => systemd-boot-random-seed.service} | 0
2 files changed, 2 insertions(+), 2 deletions(-)
rename units/{systemd-boot-system-token.service => systemd-boot-random-seed.service} (100%)
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index 3e9a89a759..3833e755b1 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -2119,9 +2119,9 @@ static int install_random_seed(const char *esp) {
return log_error_errno(r, "Failed to write 'LoaderSystemToken' EFI variable: %m");
if (r == -EINVAL)
- log_warning_errno(r, "Unable to write 'LoaderSystemToken' EFI variable (firmware problem?), ignoring: %m");
+ log_notice_errno(r, "Unable to write 'LoaderSystemToken' EFI variable (firmware problem?), ignoring: %m");
else
- log_warning_errno(r, "Unable to write 'LoaderSystemToken' EFI variable, ignoring: %m");
+ log_notice_errno(r, "Unable to write 'LoaderSystemToken' EFI variable, ignoring: %m");
} else
log_info("Successfully initialized system token in EFI variable with %zu bytes.", sizeof(buffer));
}
diff --git a/units/systemd-boot-system-token.service b/units/systemd-boot-random-seed.service
similarity index 100%
rename from units/systemd-boot-system-token.service
rename to units/systemd-boot-random-seed.service

View File

@ -0,0 +1,392 @@
From b7f74506b4a479edf2d7c5b9c08fb105e3fd7b29 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 20 Dec 2022 17:16:47 +0100
Subject: [PATCH] =?UTF-8?q?units:=20rename/rework=20systemd-boot-system-to?=
=?UTF-8?q?ken.service=20=E2=86=92=20systemd-boot-random-seed.service?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This renames systemd-boot-system-token.service to
systemd-boot-random-seed.service and conditions it less strictly.
Previously, the job of the service was to write a "system token" EFI
variable if it was missing. It called "bootctl --graceful random-seed"
for that. With this change we condition it more liberally: instead of
calling it only when the "system token" EFI variable isn't set, we call
it whenever a boot loader interface compatible boot loader is used. This
means, previously it was invoked on the first boot only: now it is
invoked at every boot.
This doesn#t change the command that is invoked. That's because
previously already the "bootctl --graceful random-seed" did two things:
set the system token if not set yet *and* refresh the random seed in the
ESP. Previousy we put the focus on the former, now we shift the focus to
the latter.
With this simple change we can replace the logic
f913c784ad4c93894fd6cb2590738113dff5a694 added, but from a service that
can run much later and doesn't keep the ESP pinned.
(cherry picked from commit 921fc451cb7ce29467c5d87346db2b8bb72fdf18)
Related: RHEL-16952
---
man/bootctl.xml | 4 +-
man/rules/meson.build | 2 +-
man/systemd-boot-random-seed.service.xml | 99 +++++++++++++++++++++++
man/systemd-boot-system-token.service.xml | 76 -----------------
man/systemd-boot.xml | 2 +-
man/systemd-random-seed.service.xml | 6 +-
units/meson.build | 2 +-
units/systemd-boot-random-seed.service | 15 ++--
units/systemd-boot-update.service | 3 +-
units/systemd-random-seed.service.in | 4 +-
10 files changed, 120 insertions(+), 93 deletions(-)
create mode 100644 man/systemd-boot-random-seed.service.xml
delete mode 100644 man/systemd-boot-system-token.service.xml
diff --git a/man/bootctl.xml b/man/bootctl.xml
index d82f12d5bb..27b45c06d3 100644
--- a/man/bootctl.xml
+++ b/man/bootctl.xml
@@ -208,7 +208,7 @@
OS and a new seed to store in the ESP from the combination of both. The random seed passed to the OS
is credited to the kernel's entropy pool by the system manager during early boot, and permits
userspace to boot up with an entropy pool fully initialized very early on. Also see
- <citerefentry><refentrytitle>systemd-boot-system-token.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+ <citerefentry><refentrytitle>systemd-boot-random-seed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
<para>See <ulink url="https://systemd.io/RANDOM_SEEDS">Random Seeds</ulink> for further
information.</para></listitem>
@@ -550,7 +550,7 @@ Boot Loader Entries:
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot Loader Specification</ulink>,
<ulink url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink>,
- <citerefentry><refentrytitle>systemd-boot-system-token.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemd-boot-random-seed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>
diff --git a/man/rules/meson.build b/man/rules/meson.build
index 9c0d773e51..beecc893fd 100644
--- a/man/rules/meson.build
+++ b/man/rules/meson.build
@@ -863,7 +863,7 @@ manpages = [
'8',
['systemd-boot-check-no-failures'],
''],
- ['systemd-boot-system-token.service', '8', [], 'HAVE_GNU_EFI'],
+ ['systemd-boot-random-seed.service', '8', [], 'HAVE_GNU_EFI'],
['systemd-boot', '7', ['sd-boot'], 'HAVE_GNU_EFI'],
['systemd-cat', '1', [], ''],
['systemd-cgls', '1', [], ''],
diff --git a/man/systemd-boot-random-seed.service.xml b/man/systemd-boot-random-seed.service.xml
new file mode 100644
index 0000000000..86ce639828
--- /dev/null
+++ b/man/systemd-boot-random-seed.service.xml
@@ -0,0 +1,99 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
+
+<refentry id="systemd-boot-random-seed.service" conditional='HAVE_GNU_EFI'
+ xmlns:xi="http://www.w3.org/2001/XInclude">
+
+ <refentryinfo>
+ <title>systemd-boot-random-seed.service</title>
+ <productname>systemd</productname>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>systemd-boot-random-seed.service</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>systemd-boot-random-seed.service</refname>
+ <refpurpose>Refresh boot loader random seed at boot</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <para><filename>systemd-boot-random-seed.service</filename></para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><filename>systemd-boot-random-seed.service</filename> is a system service that automatically
+ refreshes the boot loader random seed stored in the EFI System Partition (ESP), from the Linux kernel
+ entropy pool. The boot loader random seed is primarily consumed and updated by
+ <citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry> from the
+ UEFI environemnt (or
+ <citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry> if the
+ former is not used, but the latter is), and passed as initial RNG seed to the OS. It is an effective way
+ to ensure the OS comes up with a random pool that is fully initialized.</para>
+
+ <para>The service also automatically generates a 'system token' to store in an EFI variable in the
+ system's NVRAM. The boot loader may then combine the on-disk random seed and the system token by
+ cryptographic hashing, and pass it to the OS it boots as initialization seed for its entropy pool. Note:
+ the random seed stored in the ESP is refreshed on <emphasis>every</emphasis> reboot ensuring that
+ multiple subsequent boots will boot with different seeds. On the other hand, the system token is
+ generated randomly <emphasis>once</emphasis>, and then persistently stored in the system's EFI variable
+ storage, ensuring the same disk image won't result in the same series of boot loader seed values if used
+ on multiple systems in parallel.</para>
+
+ <para>The <filename>systemd-boot-random-seed.service</filename> unit invokes the <command>bootctl
+ random-seed</command> command, which updates the random seed in the ESP, and initializes the system
+ token if it's not initialized yet. The service is conditionalized so that it is run only when a boot
+ loader is used that implements the <ulink url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader
+ Interface</ulink>.</para> <para>For further details see
+ <citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>, regarding
+ the command this service invokes.</para>
+
+ <para>Note the relationship between <filename>systemd-boot-random-seed.service</filename> and
+ <citerefentry><refentrytitle>systemd-random-seed</refentrytitle><manvolnum>8</manvolnum></citerefentry>. The
+ former maintains the random seed consumed and updated by the boot environment (i.e. by
+ <citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry> or
+ <citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry>), the
+ latter maintains a random seed consumed and updated by the OS itself. The former ensures that the OS has
+ a filled entropy pool already during earliest boot when regular disk access is not available yet
+ (i.e. when the OS random seed cannot be loaded yet). The latter is processed much later, once writable
+ disk access is available. Thus it cannot be used to seed the initial boot phase, but typically has much
+ higher quality of entropy. Both files are consumed and updated at boot, but at different
+ times. Specifically:</para>
+
+ <orderedlist>
+ <listitem><para>In UEFI mode, the <filename>systemd-boot</filename> or
+ <filename>systemd-stub</filename> components load the boot loader random seed off the ESP, hash it with
+ available entropy and the system token, and then update it on disk. A derived seed is passed to the
+ kernel which writes it to its entropy pool.</para></listitem>
+
+ <listitem><para>In userspace the <filename>systemd-random-seed.service</filename> service loads the OS
+ random seed, writes it to the kernel entropy pool, and then updates it on disk with a new value derived
+ from the kernel entropy pool.</para></listitem>
+
+ <listitem><para>In userspace the <filename>systemd-boot-random-seed.service</filename> service updates
+ the boot loader random seed with a new value derived from the kernel kernel entropy pool.</para></listitem>
+ </orderedlist>
+
+ <para>This logic should ensure that the kernel's entropy pool is seeded during earliest bool already, if
+ possible, but the highest quality entropy is propagated back to both on-disk seeds.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-random-seed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/systemd-boot-system-token.service.xml b/man/systemd-boot-system-token.service.xml
deleted file mode 100644
index f2e30a9b13..0000000000
--- a/man/systemd-boot-system-token.service.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version='1.0'?> <!--*-nxml-*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
-
-<refentry id="systemd-boot-system-token.service" conditional='HAVE_GNU_EFI'
- xmlns:xi="http://www.w3.org/2001/XInclude">
-
- <refentryinfo>
- <title>systemd-boot-system-token.service</title>
- <productname>systemd</productname>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>systemd-boot-system-token.service</refentrytitle>
- <manvolnum>8</manvolnum>
- </refmeta>
-
- <refnamediv>
- <refname>systemd-boot-system-token.service</refname>
- <refpurpose>Generate an initial boot loader system token and random seed</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <para><filename>systemd-boot-system-token.service</filename></para>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Description</title>
-
- <para><filename>systemd-boot-system-token.service</filename> is a system service that automatically
- generates a 'system token' to store in an EFI variable in the system's NVRAM and a random seed to store
- on the EFI System Partition ESP on disk. The boot loader may then combine these two randomized data
- fields by cryptographic hashing, and pass it to the OS it boots as initialization seed for its entropy
- pool. The random seed stored in the ESP is refreshed on each reboot ensuring that multiple subsequent
- boots will boot with different seeds. The 'system token' is generated randomly once, and then
- persistently stored in the system's EFI variable storage.</para>
-
- <para>The <filename>systemd-boot-system-token.service</filename> unit invokes the <command>bootctl
- random-seed</command> command, which updates the random seed in the ESP, and initializes the 'system
- token' if it's not initialized yet. The service is conditionalized so that it is run only when all of the
- below apply:</para>
-
- <itemizedlist>
- <listitem><para>A boot loader is used that implements the <ulink
- url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink> (which defines the 'system
- token' concept).</para></listitem>
-
- <listitem><para>Either a 'system token' was not set yet, or the boot loader has not passed the OS a
- random seed yet (and thus most likely has been missing the random seed file in the
- ESP).</para></listitem>
-
- <listitem><para>The system is not running in a VM environment. This case is explicitly excluded since
- on VM environments the ESP backing storage and EFI variable storage is typically not physically
- separated and hence booting the same OS image in multiple instances would replicate both, thus reusing
- the same random seed and 'system token' among all instances, which defeats its purpose. Note that it's
- still possible to use boot loader random seed provisioning in this mode, but the automatic logic
- implemented by this service has no effect then, and the user instead has to manually invoke the
- <command>bootctl random-seed</command> acknowledging these restrictions.</para></listitem>
- </itemizedlist>
-
- <para>For further details see
- <citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>, regarding
- the command this service invokes.</para>
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- </para>
- </refsect1>
-
-</refentry>
diff --git a/man/systemd-boot.xml b/man/systemd-boot.xml
index f96c4c6512..773d6988e3 100644
--- a/man/systemd-boot.xml
+++ b/man/systemd-boot.xml
@@ -526,7 +526,7 @@
<citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>loader.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-bless-boot.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd-boot-system-token.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-boot-random-seed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>kernel-install</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot Loader Specification</ulink>,
diff --git a/man/systemd-random-seed.service.xml b/man/systemd-random-seed.service.xml
index a1e31cd460..bc8cf50a39 100644
--- a/man/systemd-random-seed.service.xml
+++ b/man/systemd-random-seed.service.xml
@@ -18,7 +18,7 @@
<refnamediv>
<refname>systemd-random-seed.service</refname>
<refname>systemd-random-seed</refname>
- <refpurpose>Load and save the system random seed at boot and shutdown</refpurpose>
+ <refpurpose>Load and save the OS system random seed at boot and shutdown</refpurpose>
</refnamediv>
<refsynopsisdiv>
@@ -86,7 +86,9 @@
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>random</refentrytitle><manvolnum>4</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>4</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>4</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-boot-random-seed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/units/meson.build b/units/meson.build
index 3a1f5229a0..cfc96a9111 100644
--- a/units/meson.build
+++ b/units/meson.build
@@ -105,7 +105,7 @@ units = [
['systemd-ask-password-wall.path', '',
'multi-user.target.wants/'],
['systemd-ask-password-wall.service', ''],
- ['systemd-boot-system-token.service', 'HAVE_GNU_EFI',
+ ['systemd-boot-random-seed.service', 'HAVE_GNU_EFI',
'sysinit.target.wants/'],
['systemd-boot-update.service', 'HAVE_GNU_EFI'],
['systemd-coredump.socket', 'ENABLE_COREDUMP',
diff --git a/units/systemd-boot-random-seed.service b/units/systemd-boot-random-seed.service
index ef5577549e..4fa286071d 100644
--- a/units/systemd-boot-random-seed.service
+++ b/units/systemd-boot-random-seed.service
@@ -8,22 +8,21 @@
# (at your option) any later version.
[Unit]
-Description=Store a System Token in an EFI Variable
-Documentation=man:systemd-boot-system-token.service(8)
+Description=Update Boot Loader Random Seed
+Documentation=man:systemd-boot-random-seed.service(8) man:random(4)
DefaultDependencies=no
After=local-fs.target systemd-random-seed.service
-Conflicts=shutdown.target initrd-switch-root.target
-Before=shutdown.target initrd-switch-root.target
+Conflicts=shutdown.target
+Before=sysinit.target shutdown.target
+ConditionVirtualization=!container
+ConditionPathExists=!/etc/initrd-release
# Only run this if the boot loader can support random seed initialization.
ConditionPathExists=|/sys/firmware/efi/efivars/LoaderFeatures-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
ConditionPathExists=|/sys/firmware/efi/efivars/StubFeatures-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
-# Only run this if there is no system token defined yet
-ConditionPathExists=!/sys/firmware/efi/efivars/LoaderSystemToken-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
-
[Service]
Type=oneshot
RemainAfterExit=yes
-ExecStart=bootctl random-seed --graceful
+ExecStart=bootctl --graceful random-seed
diff --git a/units/systemd-boot-update.service b/units/systemd-boot-update.service
index 61ff12762a..fe63fde35a 100644
--- a/units/systemd-boot-update.service
+++ b/units/systemd-boot-update.service
@@ -10,9 +10,10 @@
[Unit]
Description=Automatic Boot Loader Update
Documentation=man:bootctl(1)
+
DefaultDependencies=no
-Conflicts=shutdown.target
After=local-fs.target
+Conflicts=shutdown.target
Before=sysinit.target shutdown.target systemd-update-done.service
[Service]
diff --git a/units/systemd-random-seed.service.in b/units/systemd-random-seed.service.in
index 1aa9af9710..d57b2d1269 100644
--- a/units/systemd-random-seed.service.in
+++ b/units/systemd-random-seed.service.in
@@ -8,14 +8,16 @@
# (at your option) any later version.
[Unit]
-Description=Load/Save Random Seed
+Description=Load/Save OS Random Seed
Documentation=man:systemd-random-seed.service(8) man:random(4)
+
DefaultDependencies=no
RequiresMountsFor={{RANDOM_SEED}}
Conflicts=shutdown.target
After=systemd-remount-fs.service
Before=first-boot-complete.target shutdown.target
Wants=first-boot-complete.target
+
ConditionVirtualization=!container
ConditionPathExists=!/etc/initrd-release

View File

@ -0,0 +1,171 @@
From 6fb21c25c859d950c1d9ab3b954573e87e87e64a Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Tue, 20 Dec 2022 18:03:06 +0100
Subject: [PATCH] bootctl: split out setting of system token into function of
its own
Let's break a huge function in two. No code change, just some
refactoring.
(cherry picked from commit 54978e3f3b5394d26f53f4753bb1c9e3e5811408)
Related: RHEL-16952
---
src/boot/bootctl.c | 132 +++++++++++++++++++++++----------------------
1 file changed, 69 insertions(+), 63 deletions(-)
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index 3833e755b1..00e8eda992 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -1984,12 +1984,79 @@ static int verb_list(int argc, char *argv[], void *userdata) {
return show_boot_entries(&config, arg_json_format_flags);
}
+static int set_system_token(void) {
+ uint8_t buffer[RANDOM_EFI_SEED_SIZE];
+ size_t token_size;
+ int r;
+
+ if (!arg_touch_variables)
+ return 0;
+
+ if (arg_root) {
+ log_warning("Acting on %s, skipping EFI variable setup.",
+ arg_image ? "image" : "root directory");
+ return 0;
+ }
+
+ if (!is_efi_boot()) {
+ log_notice("Not booted with EFI, skipping EFI variable setup.");
+ return 0;
+ }
+
+ r = getenv_bool("SYSTEMD_WRITE_SYSTEM_TOKEN");
+ if (r < 0) {
+ if (r != -ENXIO)
+ log_warning_errno(r, "Failed to parse $SYSTEMD_WRITE_SYSTEM_TOKEN, ignoring.");
+ } else if (r == 0) {
+ log_notice("Not writing system token, because $SYSTEMD_WRITE_SYSTEM_TOKEN is set to false.");
+ return 0;
+ }
+
+ r = efi_get_variable(EFI_LOADER_VARIABLE(LoaderSystemToken), NULL, NULL, &token_size);
+ if (r == -ENODATA)
+ log_debug_errno(r, "LoaderSystemToken EFI variable is invalid (too short?), replacing.");
+ else if (r < 0) {
+ if (r != -ENOENT)
+ return log_error_errno(r, "Failed to test system token validity: %m");
+ } else {
+ if (token_size >= sizeof(buffer)) {
+ /* Let's avoid writes if we can, and initialize this only once. */
+ log_debug("System token already written, not updating.");
+ return 0;
+ }
+
+ log_debug("Existing system token size (%zu) does not match our expectations (%zu), replacing.", token_size, sizeof(buffer));
+ }
+
+ r = crypto_random_bytes(buffer, sizeof(buffer));
+ if (r < 0)
+ return log_error_errno(r, "Failed to acquire random seed: %m");
+
+ /* Let's write this variable with an umask in effect, so that unprivileged users can't see the token
+ * and possibly get identification information or too much insight into the kernel's entropy pool
+ * state. */
+ RUN_WITH_UMASK(0077) {
+ r = efi_set_variable(EFI_LOADER_VARIABLE(LoaderSystemToken), buffer, sizeof(buffer));
+ if (r < 0) {
+ if (!arg_graceful)
+ return log_error_errno(r, "Failed to write 'LoaderSystemToken' EFI variable: %m");
+
+ if (r == -EINVAL)
+ log_notice_errno(r, "Unable to write 'LoaderSystemToken' EFI variable (firmware problem?), ignoring: %m");
+ else
+ log_notice_errno(r, "Unable to write 'LoaderSystemToken' EFI variable, ignoring: %m");
+ } else
+ log_info("Successfully initialized system token in EFI variable with %zu bytes.", sizeof(buffer));
+ }
+
+ return 0;
+}
+
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;
@@ -2066,68 +2133,7 @@ static int install_random_seed(const char *esp) {
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;
-
- if (!is_efi_boot()) {
- log_notice("Not booted with EFI, skipping EFI variable setup.");
- return 0;
- }
-
- if (arg_root) {
- log_warning("Acting on %s, skipping EFI variable setup.",
- arg_image ? "image" : "root directory");
- return 0;
- }
-
- r = getenv_bool("SYSTEMD_WRITE_SYSTEM_TOKEN");
- if (r < 0) {
- if (r != -ENXIO)
- log_warning_errno(r, "Failed to parse $SYSTEMD_WRITE_SYSTEM_TOKEN, ignoring.");
- } else if (r == 0) {
- log_notice("Not writing system token, because $SYSTEMD_WRITE_SYSTEM_TOKEN is set to false.");
- return 0;
- }
-
- r = efi_get_variable(EFI_LOADER_VARIABLE(LoaderSystemToken), NULL, NULL, &token_size);
- if (r == -ENODATA)
- log_debug_errno(r, "LoaderSystemToken EFI variable is invalid (too short?), replacing.");
- else if (r < 0) {
- if (r != -ENOENT)
- return log_error_errno(r, "Failed to test system token validity: %m");
- } else {
- if (token_size >= sizeof(buffer)) {
- /* Let's avoid writes if we can, and initialize this only once. */
- log_debug("System token already written, not updating.");
- return 0;
- }
-
- log_debug("Existing system token size (%zu) does not match our expectations (%zu), replacing.", token_size, sizeof(buffer));
- }
-
- r = crypto_random_bytes(buffer, sizeof(buffer));
- if (r < 0)
- return log_error_errno(r, "Failed to acquire random seed: %m");
-
- /* Let's write this variable with an umask in effect, so that unprivileged users can't see the token
- * and possibly get identification information or too much insight into the kernel's entropy pool
- * state. */
- RUN_WITH_UMASK(0077) {
- r = efi_set_variable(EFI_LOADER_VARIABLE(LoaderSystemToken), buffer, sizeof(buffer));
- if (r < 0) {
- if (!arg_graceful)
- return log_error_errno(r, "Failed to write 'LoaderSystemToken' EFI variable: %m");
-
- if (r == -EINVAL)
- log_notice_errno(r, "Unable to write 'LoaderSystemToken' EFI variable (firmware problem?), ignoring: %m");
- else
- log_notice_errno(r, "Unable to write 'LoaderSystemToken' EFI variable, ignoring: %m");
- } else
- log_info("Successfully initialized system token in EFI variable with %zu bytes.", sizeof(buffer));
- }
-
- return 0;
-
+ return set_system_token();
fail:
if (tmp)
(void) unlinkat(loader_dir_fd, tmp, 0);

View File

@ -21,7 +21,7 @@
Name: systemd
Url: https://systemd.io
Version: 252
Release: 30%{?dist}
Release: 31%{?dist}
# For a breakdown of the licensing, see README
License: LGPLv2+ and MIT and GPLv2+
Summary: System and Service Manager
@ -791,6 +791,14 @@ Patch0705: 0705-resolved-reduce-the-maximum-nsec3-iterations-to-100.patch
Patch0706: 0706-efi-alignment-of-the-PE-file-has-to-be-at-least-512-.patch
Patch0707: 0707-units-change-assert-to-condition-to-skip-running-in-.patch
Patch0708: 0708-ci-add-configuration-for-regression-sniffer-GA.patch
Patch0709: 0709-bootctl-rework-random-seed-logic-to-use-open_mkdir_a.patch
Patch0710: 0710-bootctl-properly-sync-fs-before-after-moving-random-.patch
Patch0711: 0711-bootctl-when-updating-EFI-random-seed-file-hash-old-.patch
Patch0712: 0712-sha256-add-helper-than-hashes-a-buffer-and-its-size.patch
Patch0713: 0713-random-seed-don-t-refresh-EFI-random-seed-from-rando.patch
Patch0714: 0714-bootctl-downgrade-graceful-messages-to-LOG_NOTICE.patch
Patch0715: 0715-units-rename-rework-systemd-boot-system-token.servic.patch
Patch0716: 0716-bootctl-split-out-setting-of-system-token-into-funct.patch
# Downstream-only patches (90009999)
@ -1656,6 +1664,16 @@ systemd-hwdb update &>/dev/null || :
%{_prefix}/lib/dracut/modules.d/70rhel-net-naming-sysattrs/*
%changelog
* Fri Mar 15 2024 systemd maintenance team <systemd-maint@redhat.com> - 252-31
- bootctl: rework random seed logic to use open_mkdir_at() and openat() (RHEL-16952)
- bootctl: properly sync fs before/after moving random seed file into place (RHEL-16952)
- bootctl: when updating EFI random seed file, hash old seed with new one (RHEL-16952)
- sha256: add helper than hashes a buffer *and* its size (RHEL-16952)
- random-seed: don't refresh EFI random seed from random-seed.c anymore (RHEL-16952)
- bootctl: downgrade graceful messages to LOG_NOTICE (RHEL-16952)
- units: rename/rework systemd-boot-system-token.service systemd-boot-random-seed.service (RHEL-16952)
- bootctl: split out setting of system token into function of its own (RHEL-16952)
* Mon Mar 11 2024 systemd maintenance team <systemd-maint@redhat.com> - 252-30
- resolved: limit the number of signature validations in a transaction (RHEL-26643)
- resolved: reduce the maximum nsec3 iterations to 100 (RHEL-26643)