From a83ff382a56989bb32160752c66b312eacf3ba7a Mon Sep 17 00:00:00 2001 From: Jan Macku Date: Fri, 15 Mar 2024 14:22:25 +0100 Subject: [PATCH] systemd-252-31 Resolves: RHEL-16952 --- ...andom-seed-logic-to-use-open_mkdir_a.patch | 120 ++++++ ...-sync-fs-before-after-moving-random-.patch | 51 +++ ...ating-EFI-random-seed-file-hash-old-.patch | 90 ++++ ...er-than-hashes-a-buffer-and-its-size.patch | 101 +++++ ...t-refresh-EFI-random-seed-from-rando.patch | 191 +++++++++ ...rade-graceful-messages-to-LOG_NOTICE.patch | 34 ++ ...ork-systemd-boot-system-token.servic.patch | 392 ++++++++++++++++++ ...t-setting-of-system-token-into-funct.patch | 171 ++++++++ systemd.spec | 20 +- 9 files changed, 1169 insertions(+), 1 deletion(-) create mode 100644 0709-bootctl-rework-random-seed-logic-to-use-open_mkdir_a.patch create mode 100644 0710-bootctl-properly-sync-fs-before-after-moving-random-.patch create mode 100644 0711-bootctl-when-updating-EFI-random-seed-file-hash-old-.patch create mode 100644 0712-sha256-add-helper-than-hashes-a-buffer-and-its-size.patch create mode 100644 0713-random-seed-don-t-refresh-EFI-random-seed-from-rando.patch create mode 100644 0714-bootctl-downgrade-graceful-messages-to-LOG_NOTICE.patch create mode 100644 0715-units-rename-rework-systemd-boot-system-token.servic.patch create mode 100644 0716-bootctl-split-out-setting-of-system-token-into-funct.patch diff --git a/0709-bootctl-rework-random-seed-logic-to-use-open_mkdir_a.patch b/0709-bootctl-rework-random-seed-logic-to-use-open_mkdir_a.patch new file mode 100644 index 0000000..24822c7 --- /dev/null +++ b/0709-bootctl-rework-random-seed-logic-to-use-open_mkdir_a.patch @@ -0,0 +1,120 @@ +From e12d41f584e33c0183a47d6c7211ccbf23f3e6a4 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +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) { diff --git a/0710-bootctl-properly-sync-fs-before-after-moving-random-.patch b/0710-bootctl-properly-sync-fs-before-after-moving-random-.patch new file mode 100644 index 0000000..cbf3221 --- /dev/null +++ b/0710-bootctl-properly-sync-fs-before-after-moving-random-.patch @@ -0,0 +1,51 @@ +From 30aa0b51b3edba2cda99abf32e7965afb4ea311c Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +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; + } + diff --git a/0711-bootctl-when-updating-EFI-random-seed-file-hash-old-.patch b/0711-bootctl-when-updating-EFI-random-seed-file-hash-old-.patch new file mode 100644 index 0000000..abc6ac3 --- /dev/null +++ b/0711-bootctl-when-updating-EFI-random-seed-file-hash-old-.patch @@ -0,0 +1,90 @@ +From a698bb3a2dd4fec2302e0aebef4d8359d8d4cf40 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +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; diff --git a/0712-sha256-add-helper-than-hashes-a-buffer-and-its-size.patch b/0712-sha256-add-helper-than-hashes-a-buffer-and-its-size.patch new file mode 100644 index 0000000..12076bd --- /dev/null +++ b/0712-sha256-add-helper-than-hashes-a-buffer-and-its-size.patch @@ -0,0 +1,101 @@ +From 7b9e71d4f8d01557da700f2da11870f6246abdf2 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +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) diff --git a/0713-random-seed-don-t-refresh-EFI-random-seed-from-rando.patch b/0713-random-seed-don-t-refresh-EFI-random-seed-from-rando.patch new file mode 100644 index 0000000..4218781 --- /dev/null +++ b/0713-random-seed-don-t-refresh-EFI-random-seed-from-rando.patch @@ -0,0 +1,191 @@ +From 5c3c932aeef27dcc0b4cb91aeb7e52974add6998 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +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); diff --git a/0714-bootctl-downgrade-graceful-messages-to-LOG_NOTICE.patch b/0714-bootctl-downgrade-graceful-messages-to-LOG_NOTICE.patch new file mode 100644 index 0000000..b0cf9fb --- /dev/null +++ b/0714-bootctl-downgrade-graceful-messages-to-LOG_NOTICE.patch @@ -0,0 +1,34 @@ +From 825d1d4535a7aafd7549bc7a5de7d72b5ec2cdbd Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +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 diff --git a/0715-units-rename-rework-systemd-boot-system-token.servic.patch b/0715-units-rename-rework-systemd-boot-system-token.servic.patch new file mode 100644 index 0000000..181e6dc --- /dev/null +++ b/0715-units-rename-rework-systemd-boot-system-token.servic.patch @@ -0,0 +1,392 @@ +From b7f74506b4a479edf2d7c5b9c08fb105e3fd7b29 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +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 +- systemd-boot-system-token.service8. ++ systemd-boot-random-seed.service8. + + See Random Seeds for further + information. +@@ -550,7 +550,7 @@ Boot Loader Entries: + systemd-boot7, + Boot Loader Specification, + Boot Loader Interface, +- systemd-boot-system-token.service8 ++ systemd-boot-random-seed.service8 + + + +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ systemd-boot-random-seed.service ++ systemd ++ ++ ++ ++ systemd-boot-random-seed.service ++ 8 ++ ++ ++ ++ systemd-boot-random-seed.service ++ Refresh boot loader random seed at boot ++ ++ ++ ++ systemd-boot-random-seed.service ++ ++ ++ ++ Description ++ ++ systemd-boot-random-seed.service 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 ++ systemd-boot7 from the ++ UEFI environemnt (or ++ systemd-stub7 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. ++ ++ 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 every reboot ensuring that ++ multiple subsequent boots will boot with different seeds. On the other hand, the system token is ++ generated randomly once, 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. ++ ++ The systemd-boot-random-seed.service unit invokes the bootctl ++ random-seed 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 Boot Loader ++ Interface. For further details see ++ bootctl1, regarding ++ the command this service invokes. ++ ++ Note the relationship between systemd-boot-random-seed.service and ++ systemd-random-seed8. The ++ former maintains the random seed consumed and updated by the boot environment (i.e. by ++ systemd-boot7 or ++ systemd-stub7), 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: ++ ++ ++ In UEFI mode, the systemd-boot or ++ systemd-stub 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. ++ ++ In userspace the systemd-random-seed.service 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. ++ ++ In userspace the systemd-boot-random-seed.service service updates ++ the boot loader random seed with a new value derived from the kernel kernel entropy pool. ++ ++ ++ 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. ++ ++ ++ ++ See Also ++ ++ systemd1, ++ random4, ++ bootctl1, ++ systemd-boot7, ++ systemd-stub7, ++ systemd-random-seed.service8 ++ ++ ++ ++ +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 @@ +- +- +- +- +- +- +- +- systemd-boot-system-token.service +- systemd +- +- +- +- systemd-boot-system-token.service +- 8 +- +- +- +- systemd-boot-system-token.service +- Generate an initial boot loader system token and random seed +- +- +- +- systemd-boot-system-token.service +- +- +- +- Description +- +- systemd-boot-system-token.service 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. +- +- The systemd-boot-system-token.service unit invokes the bootctl +- random-seed 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: +- +- +- A boot loader is used that implements the Boot Loader Interface (which defines the 'system +- token' concept). +- +- 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). +- +- 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 +- bootctl random-seed acknowledging these restrictions. +- +- +- For further details see +- bootctl1, regarding +- the command this service invokes. +- +- +- +- See Also +- +- systemd1, +- bootctl1, +- systemd-boot7 +- +- +- +- +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 @@ + bootctl1, + loader.conf5, + systemd-bless-boot.service8, +- systemd-boot-system-token.service8, ++ systemd-boot-random-seed.service8, + kernel-install8, + systemd-stub7, + Boot Loader Specification, +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 @@ + + systemd-random-seed.service + systemd-random-seed +- Load and save the system random seed at boot and shutdown ++ Load and save the OS system random seed at boot and shutdown + + + +@@ -86,7 +86,9 @@ + systemd1, + random4, + systemd-boot7, +- bootctl4 ++ systemd-stub7, ++ bootctl4, ++ systemd-boot-random-seed.service8 + + + +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 + diff --git a/0716-bootctl-split-out-setting-of-system-token-into-funct.patch b/0716-bootctl-split-out-setting-of-system-token-into-funct.patch new file mode 100644 index 0000000..486e3cf --- /dev/null +++ b/0716-bootctl-split-out-setting-of-system-token-into-funct.patch @@ -0,0 +1,171 @@ +From 6fb21c25c859d950c1d9ab3b954573e87e87e64a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +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); diff --git a/systemd.spec b/systemd.spec index 8db4129..3944bfa 100644 --- a/systemd.spec +++ b/systemd.spec @@ -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 (9000–9999) @@ -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 - 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 - 252-30 - resolved: limit the number of signature validations in a transaction (RHEL-26643) - resolved: reduce the maximum nsec3 iterations to 100 (RHEL-26643)