summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Janssen <medhefgo@web.de>2021-10-20 10:11:45 +0200
committerLennart Poettering <lennart@poettering.net>2021-10-22 10:08:38 +0200
commitc49645121614c2ea0e04371a866c28cf87c9d7c5 (patch)
tree77356133c2a6ce03e85b0c491c27d4f2bd7d2db2
parentaee21f7f8f462cce682f46a2173d030bfb11afd6 (diff)
downloadsystemd-c49645121614c2ea0e04371a866c28cf87c9d7c5.tar.gz
sd-boot: Be more precise about secure boot modes
Fixes: #11559
-rw-r--r--src/basic/efivars.c25
-rw-r--r--src/basic/efivars.h7
-rw-r--r--src/boot/bootctl.c6
-rw-r--r--src/boot/efi/boot.c9
-rw-r--r--src/boot/efi/secure-boot.c17
-rw-r--r--src/boot/efi/secure-boot.h2
-rw-r--r--src/fundamental/efivars-fundamental.c36
-rw-r--r--src/fundamental/efivars-fundamental.h (renamed from src/fundamental/efi-loader-features.h)21
-rw-r--r--src/fundamental/meson.build3
-rw-r--r--src/shared/efi-loader.h2
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