diff options
author | Jan Janssen <medhefgo@web.de> | 2021-10-20 10:11:45 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2021-10-22 10:08:38 +0200 |
commit | c49645121614c2ea0e04371a866c28cf87c9d7c5 (patch) | |
tree | 77356133c2a6ce03e85b0c491c27d4f2bd7d2db2 | |
parent | aee21f7f8f462cce682f46a2173d030bfb11afd6 (diff) | |
download | systemd-c49645121614c2ea0e04371a866c28cf87c9d7c5.tar.gz |
sd-boot: Be more precise about secure boot modes
Fixes: #11559
-rw-r--r-- | src/basic/efivars.c | 25 | ||||
-rw-r--r-- | src/basic/efivars.h | 7 | ||||
-rw-r--r-- | src/boot/bootctl.c | 6 | ||||
-rw-r--r-- | src/boot/efi/boot.c | 9 | ||||
-rw-r--r-- | src/boot/efi/secure-boot.c | 17 | ||||
-rw-r--r-- | src/boot/efi/secure-boot.h | 2 | ||||
-rw-r--r-- | src/fundamental/efivars-fundamental.c | 36 | ||||
-rw-r--r-- | src/fundamental/efivars-fundamental.h (renamed from src/fundamental/efi-loader-features.h) | 21 | ||||
-rw-r--r-- | src/fundamental/meson.build | 3 | ||||
-rw-r--r-- | src/shared/efi-loader.h | 2 |
10 files changed, 111 insertions, 17 deletions
diff --git a/src/basic/efivars.c b/src/basic/efivars.c index 3e5c5e68dd..bb115a7b99 100644 --- a/src/basic/efivars.c +++ b/src/basic/efivars.c @@ -293,13 +293,28 @@ bool is_efi_secure_boot(void) { return cache > 0; } -bool is_efi_secure_boot_setup_mode(void) { - static int cache = -1; +SecureBootMode efi_get_secure_boot_mode(void) { + static SecureBootMode cache = _SECURE_BOOT_INVALID; - if (cache < 0) - cache = read_flag(EFI_GLOBAL_VARIABLE(SetupMode)); + if (cache != _SECURE_BOOT_INVALID) + return cache; - return cache > 0; + int secure = read_flag(EFI_GLOBAL_VARIABLE(SecureBoot)); + if (secure < 0) { + if (secure != -ENOENT) + log_debug_errno(secure, "Error reading SecureBoot EFI variable: %m"); + return (cache = SECURE_BOOT_UNSUPPORTED); + } + + /* We can assume false for all these if they are abscent (AuditMode and + * DeployedMode may not exist on older firmware). */ + int audit = read_flag(EFI_GLOBAL_VARIABLE(AuditMode)); + int deployed = read_flag(EFI_GLOBAL_VARIABLE(DeployedMode)); + int setup = read_flag(EFI_GLOBAL_VARIABLE(SetupMode)); + log_debug("Secure boot variables: SecureBoot=%d AuditMode=%d DeployedMode=%d SetupMode=%d", + secure, audit, deployed, setup); + + return (cache = decode_secure_boot_mode(secure, audit > 0, deployed > 0, setup > 0)); } static int read_efi_options_variable(char **line) { diff --git a/src/basic/efivars.h b/src/basic/efivars.h index cb6ad9e0a2..494154b361 100644 --- a/src/basic/efivars.h +++ b/src/basic/efivars.h @@ -10,6 +10,7 @@ #include "sd-id128.h" +#include "efivars-fundamental.h" #include "time-util.h" #define EFI_VENDOR_LOADER SD_ID128_MAKE(4a,67,b0,82,0a,4c,41,cf,b6,c7,44,0b,29,bb,8c,4f) @@ -48,7 +49,7 @@ int efi_set_variable_string(const char *variable, const char *p); bool is_efi_boot(void); bool is_efi_secure_boot(void); -bool is_efi_secure_boot_setup_mode(void); +SecureBootMode efi_get_secure_boot_mode(void); int cache_efi_options_variable(void); int systemd_efi_options_variable(char **line); @@ -80,8 +81,8 @@ static inline bool is_efi_secure_boot(void) { return false; } -static inline bool is_efi_secure_boot_setup_mode(void) { - return false; +static inline SecureBootMode efi_get_secure_boot_mode(void) { + return SECURE_BOOT_UNKNOWN; } static inline int cache_efi_options_variable(void) { diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index b0b3d4f8ae..e3e1040a4b 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -1322,10 +1322,12 @@ static int verb_status(int argc, char *argv[], void *userdata) { if (k < 0 && k != -ENOENT) r = log_warning_errno(k, "Failed to read EFI variable LoaderDevicePartUUID: %m"); + SecureBootMode secure = efi_get_secure_boot_mode(); printf("System:\n"); printf(" Firmware: %s%s (%s)%s\n", ansi_highlight(), strna(fw_type), strna(fw_info), ansi_normal()); - printf(" Secure Boot: %sd\n", enable_disable(is_efi_secure_boot())); - printf(" Setup Mode: %s\n", is_efi_secure_boot_setup_mode() ? "setup" : "user"); + printf(" Secure Boot: %sd (%s)\n", + enable_disable(IN_SET(secure, SECURE_BOOT_USER, SECURE_BOOT_DEPLOYED)), + secure_boot_mode_to_string(secure)); printf(" TPM2 Support: %s\n", yes_no(efi_has_tpm2())); k = efi_get_reboot_to_firmware(); diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 6c4ddb1939..ba097bf20c 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -8,7 +8,7 @@ #include "devicetree.h" #include "disk.h" #include "drivers.h" -#include "efi-loader-features.h" +#include "efivars-fundamental.h" #include "graphics.h" #include "linux.h" #include "measure.h" @@ -434,7 +434,7 @@ static void ps_bool(const CHAR16 *fmt, BOOLEAN value) { static void print_status(Config *config, CHAR16 *loaded_image_path) { UINT64 key; UINTN x_max, y_max; - BOOLEAN setup_mode = FALSE; + SecureBootMode secure; _cleanup_freepool_ CHAR16 *device_part_uuid = NULL, *default_efivar = NULL; assert(config); @@ -443,9 +443,9 @@ static void print_status(Config *config, CHAR16 *loaded_image_path) { clear_screen(COLOR_NORMAL); console_query_mode(&x_max, &y_max); + secure = secure_boot_mode(); (void) efivar_get(LOADER_GUID, L"LoaderDevicePartUUID", &device_part_uuid); (void) efivar_get(LOADER_GUID, L"LoaderEntryDefault", &default_efivar); - (void) efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SetupMode", &setup_mode); /* We employ some unusual indentation here for readability. */ @@ -457,8 +457,7 @@ static void print_status(Config *config, CHAR16 *loaded_image_path) { ps_string(L" firmware vendor: %s\n", ST->FirmwareVendor); Print(L" firmware version: %u.%02u\n", ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); Print(L" OS indications: %lu\n", get_os_indications_supported()); - ps_bool(L" secure boot: %s\n", secure_boot_enabled()); - ps_bool(L" setup mode: %s\n", setup_mode); + Print(L" secure boot: %s (%s)\n", yes_no(IN_SET(secure, SECURE_BOOT_USER, SECURE_BOOT_DEPLOYED)), secure_boot_mode_to_string(secure)); ps_bool(L" shim: %s\n", shim_loaded()); Print(L" console mode: %d/%d (%lu x %lu)\n", ST->ConOut->Mode->Mode, ST->ConOut->Mode->MaxMode - 1LL, x_max, y_max); diff --git a/src/boot/efi/secure-boot.c b/src/boot/efi/secure-boot.c index c1dfcfc5cb..efea145719 100644 --- a/src/boot/efi/secure-boot.c +++ b/src/boot/efi/secure-boot.c @@ -12,6 +12,23 @@ BOOLEAN secure_boot_enabled(void) { return !EFI_ERROR(err) && secure; } +SecureBootMode secure_boot_mode(void) { + BOOLEAN secure, audit = FALSE, deployed = FALSE, setup = FALSE; + EFI_STATUS err; + + err = efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SecureBoot", &secure); + if (EFI_ERROR(err)) + return SECURE_BOOT_UNSUPPORTED; + + /* We can assume FALSE for all these if they are abscent (AuditMode and + * DeployedMode may not exist on older firmware). */ + (void) efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"AuditMode", &audit); + (void) efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"DeployedMode", &deployed); + (void) efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SetupMode", &setup); + + return decode_secure_boot_mode(secure, audit, deployed, setup); +} + #ifdef SBAT_DISTRO static const char sbat[] _used_ _section_ (".sbat") _align_ (512) = "sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md\n" diff --git a/src/boot/efi/secure-boot.h b/src/boot/efi/secure-boot.h index d06a7deaaa..d5f6ba82d4 100644 --- a/src/boot/efi/secure-boot.h +++ b/src/boot/efi/secure-boot.h @@ -2,5 +2,7 @@ #pragma once #include <efi.h> +#include "efivars-fundamental.h" BOOLEAN secure_boot_enabled(void); +SecureBootMode secure_boot_mode(void); diff --git a/src/fundamental/efivars-fundamental.c b/src/fundamental/efivars-fundamental.c new file mode 100644 index 0000000000..6e22232baa --- /dev/null +++ b/src/fundamental/efivars-fundamental.c @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "efivars-fundamental.h" + +static const sd_char * const table[_SECURE_BOOT_MAX] = { + [SECURE_BOOT_UNSUPPORTED] = STR_C("unsupported"), + [SECURE_BOOT_UNKNOWN] = STR_C("unknown"), + [SECURE_BOOT_AUDIT] = STR_C("audit"), + [SECURE_BOOT_DEPLOYED] = STR_C("deployed"), + [SECURE_BOOT_SETUP] = STR_C("setup"), + [SECURE_BOOT_USER] = STR_C("user"), +}; + +const sd_char *secure_boot_mode_to_string(SecureBootMode m) { + return (m >= 0 && m < _SECURE_BOOT_MAX) ? table[m] : NULL; +} + +SecureBootMode decode_secure_boot_mode( + sd_bool secure, + sd_bool audit, + sd_bool deployed, + sd_bool setup) { + + /* See figure 32-4 Secure Boot Modes from UEFI Specification 2.9 */ + if (secure && deployed && !audit && !setup) + return SECURE_BOOT_DEPLOYED; + if (secure && !deployed && !audit && !setup) + return SECURE_BOOT_USER; + if (!secure && !deployed && audit && setup) + return SECURE_BOOT_AUDIT; + if (!secure && !deployed && !audit && setup) + return SECURE_BOOT_SETUP; + + /* Well, this should not happen. */ + return SECURE_BOOT_UNKNOWN; +} diff --git a/src/fundamental/efi-loader-features.h b/src/fundamental/efivars-fundamental.h index 287ae3c892..a70810a8d3 100644 --- a/src/fundamental/efi-loader-features.h +++ b/src/fundamental/efivars-fundamental.h @@ -1,6 +1,9 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include <errno.h> +#include "string-util-fundamental.h" + #ifndef UINT64_C # define UINT64_C(c) (c ## ULL) #endif @@ -13,3 +16,21 @@ #define EFI_LOADER_FEATURE_XBOOTLDR (UINT64_C(1) << 5) #define EFI_LOADER_FEATURE_RANDOM_SEED (UINT64_C(1) << 6) #define EFI_LOADER_FEATURE_LOAD_DRIVER (UINT64_C(1) << 7) + +typedef enum SecureBootMode { + SECURE_BOOT_UNSUPPORTED, + SECURE_BOOT_UNKNOWN, + SECURE_BOOT_AUDIT, + SECURE_BOOT_DEPLOYED, + SECURE_BOOT_SETUP, + SECURE_BOOT_USER, + _SECURE_BOOT_MAX, + _SECURE_BOOT_INVALID = -EINVAL, +} SecureBootMode; + +const sd_char *secure_boot_mode_to_string(SecureBootMode m); +SecureBootMode decode_secure_boot_mode( + sd_bool secure, + sd_bool audit, + sd_bool deployed, + sd_bool setup); diff --git a/src/fundamental/meson.build b/src/fundamental/meson.build index 3aa9fab8cb..3c9f07b191 100644 --- a/src/fundamental/meson.build +++ b/src/fundamental/meson.build @@ -3,13 +3,14 @@ fundamental_path = meson.current_source_dir() fundamental_headers = files( - 'efi-loader-features.h', + 'efivars-fundamental.h', 'macro-fundamental.h', 'string-util-fundamental.h', 'sha256.h', 'type.h') sources = ''' + efivars-fundamental.c string-util-fundamental.c sha256.c '''.split() diff --git a/src/shared/efi-loader.h b/src/shared/efi-loader.h index bc5769bb6b..7a100e5364 100644 --- a/src/shared/efi-loader.h +++ b/src/shared/efi-loader.h @@ -3,7 +3,7 @@ #include <sys/stat.h> -#include "efi-loader-features.h" +#include "efivars-fundamental.h" #include "efivars.h" #if ENABLE_EFI |