You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
7.3 KiB
172 lines
7.3 KiB
7 months ago
|
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);
|