diff options
author | Filipe Brandenburger <filbranden@gmail.com> | 2020-06-11 00:11:32 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2020-06-13 14:46:57 +0200 |
commit | 209b2592ed5883bdfc7a0f2e5b7277c5c4fe834e (patch) | |
tree | 5941e3b132a3948a15181a89af49eaf668b9122a /src | |
parent | test: in test_bridge_configure_without_carrier, ignore setup_state (diff) | |
download | systemd-209b2592ed5883bdfc7a0f2e5b7277c5c4fe834e.tar.xz systemd-209b2592ed5883bdfc7a0f2e5b7277c5c4fe834e.zip |
efi: Cache contents of EFI variable SystemdOptions
Cache it early in startup of the system manager, right after `/run/systemd` is
created, so that further access to it can be done without accessing the EFI
filesystem at all.
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/efivars.c | 73 | ||||
-rw-r--r-- | src/basic/efivars.h | 1 | ||||
-rw-r--r-- | src/core/main.c | 5 |
3 files changed, 59 insertions, 20 deletions
diff --git a/src/basic/efivars.c b/src/basic/efivars.c index 3954bd62f5..e7edd17d0b 100644 --- a/src/basic/efivars.c +++ b/src/basic/efivars.c @@ -14,6 +14,7 @@ #include "chattr-util.h" #include "efivars.h" #include "fd-util.h" +#include "fileio.h" #include "io-util.h" #include "macro.h" #include "stdio-util.h" @@ -40,6 +41,17 @@ char* efi_variable_path(sd_id128_t vendor, const char *name) { return p; } +static char* efi_variable_cache_path(sd_id128_t vendor, const char *name) { + char *p; + + if (asprintf(&p, + "/run/systemd/efivars/%s-" SD_ID128_UUID_FORMAT_STR, + name, SD_ID128_FORMAT_VAL(vendor)) < 0) + return NULL; + + return p; +} + int efi_get_variable( sd_id128_t vendor, const char *name, @@ -323,32 +335,17 @@ bool is_efi_secure_boot_setup_mode(void) { return cache > 0; } -int systemd_efi_options_variable(char **line) { - const char *e; +int cache_efi_options_variable(void) { + _cleanup_free_ char *line = NULL, *cachepath = NULL; int r; - assert(line); - - /* For testing purposes it is sometimes useful to be able to override this */ - e = secure_getenv("SYSTEMD_EFI_OPTIONS"); - if (e) { - char *m; - - m = strdup(e); - if (!m) - return -ENOMEM; - - *line = m; - return 0; - } - /* In SecureBoot mode this is probably not what you want. As your cmdline is cryptographically signed * like when using Type #2 EFI Unified Kernel Images (https://systemd.io/BOOT_LOADER_SPECIFICATION/) * The user's intention is then that the cmdline should not be modified. You want to make sure that * the system starts up as exactly specified in the signed artifact. * - * (NB: to make testing purposes we still check the $SYSTEMD_EFI_OPTIONS env var above, even when in - * SecureBoot mode.) */ + * (NB: For testing purposes, we still check the $SYSTEMD_EFI_OPTIONS env var before accessing this + * cache, even when in SecureBoot mode.) */ if (is_efi_secure_boot()) { _cleanup_free_ char *k; @@ -365,10 +362,46 @@ int systemd_efi_options_variable(char **line) { return -EPERM; } - r = efi_get_variable_string(EFI_VENDOR_SYSTEMD, "SystemdOptions", line); + r = efi_get_variable_string(EFI_VENDOR_SYSTEMD, "SystemdOptions", &line); if (r == -ENOENT) return -ENODATA; + if (r < 0) + return r; + cachepath = efi_variable_cache_path(EFI_VENDOR_SYSTEMD, "SystemdOptions"); + if (!cachepath) + return -ENOMEM; + + return write_string_file(cachepath, line, WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_MKDIR_0755); +} + +int systemd_efi_options_variable(char **line) { + const char *e; + _cleanup_free_ char *cachepath = NULL; + int r; + + assert(line); + + /* For testing purposes it is sometimes useful to be able to override this */ + e = secure_getenv("SYSTEMD_EFI_OPTIONS"); + if (e) { + char *m; + + m = strdup(e); + if (!m) + return -ENOMEM; + + *line = m; + return 0; + } + + cachepath = efi_variable_cache_path(EFI_VENDOR_SYSTEMD, "SystemdOptions"); + if (!cachepath) + return -ENOMEM; + + r = read_one_line_file(cachepath, line); + if (r == -ENOENT) + return -ENODATA; return r; } #endif diff --git a/src/basic/efivars.h b/src/basic/efivars.h index 13a33c6605..80854677f4 100644 --- a/src/basic/efivars.h +++ b/src/basic/efivars.h @@ -32,6 +32,7 @@ bool is_efi_boot(void); bool is_efi_secure_boot(void); bool is_efi_secure_boot_setup_mode(void); +int cache_efi_options_variable(void); int systemd_efi_options_variable(char **line); #else diff --git a/src/core/main.c b/src/core/main.c index a88d779448..6e606d412a 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -33,6 +33,7 @@ #include "dbus.h" #include "def.h" #include "efi-random.h" +#include "efivars.h" #include "emergency-action.h" #include "env-util.h" #include "exit-status.h" @@ -2630,6 +2631,10 @@ int main(int argc, char *argv[]) { /* The efivarfs is now mounted, let's read the random seed off it */ (void) efi_take_random_seed(); + + /* Cache command-line options passed from EFI variables */ + if (!skip_setup) + (void) cache_efi_options_variable(); } /* Save the original RLIMIT_NOFILE/RLIMIT_MEMLOCK so that we can reset it later when |