From 484f4e5b2d62e885998fa3c09ed4d58b6c38f987 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 30 Apr 2020 10:08:54 +0200 Subject: efi: honour SYSTEMD_EFI_OPTIONS even if we wouldn't honour SystemdOptions EFI var due to SecureBoot Fixes: #14864 --- src/basic/efivars.c | 23 +++++++++++++++++++++++ src/basic/proc-cmdline.c | 16 ++-------------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/basic/efivars.c b/src/basic/efivars.c index b79ca8efd7..5529113bc5 100644 --- a/src/basic/efivars.c +++ b/src/basic/efivars.c @@ -313,6 +313,29 @@ int systemd_efi_options_variable(char **line) { 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.) */ + if (is_efi_secure_boot()) { + _cleanup_free_ char *k; + + k = efi_variable_path(EFI_VENDOR_SYSTEMD, "SystemdOptions"); + if (!k) + return -ENOMEM; + + /* Let's be helpful with the returned error and check if the variable exists at all. If it + * does, let's return a recognizable error (EPERM), and if not ENODATA. */ + + if (access(k, F_OK) < 0) + return errno == -ENOENT ? -ENODATA : -errno; + + return -EPERM; + } + r = efi_get_variable_string(EFI_VENDOR_SYSTEMD, "SystemdOptions", line); if (r == -ENOENT) return -ENODATA; diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c index 1af58717c6..d3d99d9a7f 100644 --- a/src/basic/proc-cmdline.c +++ b/src/basic/proc-cmdline.c @@ -39,18 +39,6 @@ int proc_cmdline(char **ret) { return read_one_line_file("/proc/cmdline", ret); } -/* 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. */ -static int systemd_options_variable(char **line) { - if (is_efi_secure_boot()) - return -ENODATA; - - return systemd_efi_options_variable(line); -} - static int proc_cmdline_extract_first(const char **p, char **ret_word, ProcCmdlineFlags flags) { const char *q = *p; int r; @@ -131,7 +119,7 @@ int proc_cmdline_parse(proc_cmdline_parse_t parse_item, void *data, ProcCmdlineF /* We parse the EFI variable first, because later settings have higher priority. */ - r = systemd_options_variable(&line); + r = systemd_efi_options_variable(&line); if (r < 0 && r != -ENODATA) log_debug_errno(r, "Failed to get SystemdOptions EFI variable, ignoring: %m"); @@ -262,7 +250,7 @@ int proc_cmdline_get_key(const char *key, ProcCmdlineFlags flags, char **ret_val return r; line = mfree(line); - r = systemd_options_variable(&line); + r = systemd_efi_options_variable(&line); if (r == -ENODATA) return false; /* Not found */ if (r < 0) -- cgit v1.2.1