1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-12-23 17:34:00 +03:00

sd-boot: Be more precise about secure boot modes

Fixes: #11559
This commit is contained in:
Jan Janssen 2021-10-20 10:11:45 +02:00 committed by Lennart Poettering
parent aee21f7f8f
commit c496451216
10 changed files with 111 additions and 17 deletions

View File

@ -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) {

View File

@ -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) {

View File

@ -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();

View File

@ -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);

View File

@ -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"

View File

@ -2,5 +2,7 @@
#pragma once
#include <efi.h>
#include "efivars-fundamental.h"
BOOLEAN secure_boot_enabled(void);
SecureBootMode secure_boot_mode(void);

View File

@ -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;
}

View File

@ -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);

View File

@ -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()

View File

@ -3,7 +3,7 @@
#include <sys/stat.h>
#include "efi-loader-features.h"
#include "efivars-fundamental.h"
#include "efivars.h"
#if ENABLE_EFI