From ce0f078f4d23690e3b5d870e062e35aeaf581e7e Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Sat, 30 Jan 2021 22:18:01 +0000 Subject: [PATCH 01/12] boot: Move Secure Boot logic to new file --- src/boot/efi/boot.c | 6 +++--- src/boot/efi/meson.build | 1 + src/boot/efi/random-seed.c | 2 +- src/boot/efi/secure-boot.c | 16 ++++++++++++++++ src/boot/efi/secure-boot.h | 6 ++++++ src/boot/efi/shim.c | 11 ----------- src/boot/efi/shim.h | 2 -- src/boot/efi/stub.c | 13 +++---------- 8 files changed, 30 insertions(+), 27 deletions(-) create mode 100644 src/boot/efi/secure-boot.c create mode 100644 src/boot/efi/secure-boot.h diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index e1a7dd1f32e..0d516e00dc5 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -13,6 +13,7 @@ #include "measure.h" #include "pe.h" #include "random-seed.h" +#include "secure-boot.h" #include "shim.h" #include "util.h" @@ -359,7 +360,7 @@ static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) { static VOID print_status(Config *config, CHAR16 *loaded_image_path) { UINT64 key; UINTN i; - _cleanup_freepool_ CHAR8 *bootvar = NULL, *modevar = NULL, *indvar = NULL; + _cleanup_freepool_ CHAR8 *modevar = NULL, *indvar = NULL; _cleanup_freepool_ CHAR16 *partstr = NULL, *defaultstr = NULL; UINTN x, y, size; @@ -376,8 +377,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { if (uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &x, &y) == EFI_SUCCESS) Print(L"console size: %d x %d\n", x, y); - if (efivar_get_raw(&global_guid, L"SecureBoot", &bootvar, &size) == EFI_SUCCESS) - Print(L"SecureBoot: %s\n", yes_no(*bootvar > 0)); + Print(L"SecureBoot: %s\n", yes_no(secure_boot_enabled())); if (efivar_get_raw(&global_guid, L"SetupMode", &modevar, &size) == EFI_SUCCESS) Print(L"SetupMode: %s\n", *modevar > 0 ? L"setup" : L"user"); diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 24177f93840..875a501b30b 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -21,6 +21,7 @@ common_sources = ''' graphics.c measure.c pe.c + secure-boot.c util.c '''.split() diff --git a/src/boot/efi/random-seed.c b/src/boot/efi/random-seed.c index 895c85445ef..18e686b3a80 100644 --- a/src/boot/efi/random-seed.c +++ b/src/boot/efi/random-seed.c @@ -5,9 +5,9 @@ #include "missing_efi.h" #include "random-seed.h" +#include "secure-boot.h" #include "sha256.h" #include "util.h" -#include "shim.h" #define RANDOM_MAX_SIZE_MIN (32U) #define RANDOM_MAX_SIZE_MAX (32U*1024U) diff --git a/src/boot/efi/secure-boot.c b/src/boot/efi/secure-boot.c new file mode 100644 index 00000000000..cea7e288289 --- /dev/null +++ b/src/boot/efi/secure-boot.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "secure-boot.h" +#include "util.h" + +static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE; + +BOOLEAN secure_boot_enabled(void) { + _cleanup_freepool_ CHAR8 *b = NULL; + UINTN size; + + if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS) + return *b > 0; + + return FALSE; +} diff --git a/src/boot/efi/secure-boot.h b/src/boot/efi/secure-boot.h new file mode 100644 index 00000000000..d06a7deaaa3 --- /dev/null +++ b/src/boot/efi/secure-boot.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include + +BOOLEAN secure_boot_enabled(void); diff --git a/src/boot/efi/shim.c b/src/boot/efi/shim.c index 3dc10089c6c..2039603260b 100644 --- a/src/boot/efi/shim.c +++ b/src/boot/efi/shim.c @@ -31,7 +31,6 @@ struct ShimLock { }; static const EFI_GUID simple_fs_guid = SIMPLE_FILE_SYSTEM_PROTOCOL; -static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE; static const EFI_GUID security_protocol_guid = { 0xa46423e3, 0x4617, 0x49f1, {0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39 } }; static const EFI_GUID security2_protocol_guid = { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } }; @@ -58,16 +57,6 @@ static BOOLEAN shim_validate(VOID *data, UINT32 size) { return shim_lock->shim_verify(data, size) == EFI_SUCCESS; } -BOOLEAN secure_boot_enabled(void) { - _cleanup_freepool_ CHAR8 *b = NULL; - UINTN size; - - if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS) - return *b > 0; - - return FALSE; -} - /* * See the UEFI Platform Initialization manual (Vol2: DXE) for this */ diff --git a/src/boot/efi/shim.h b/src/boot/efi/shim.h index e24fcdac540..d682994b9e5 100644 --- a/src/boot/efi/shim.h +++ b/src/boot/efi/shim.h @@ -13,6 +13,4 @@ BOOLEAN shim_loaded(void); -BOOLEAN secure_boot_enabled(void); - EFI_STATUS security_policy_install(void); diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index a09f47c7119..eb6ce61bb95 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -8,19 +8,15 @@ #include "linux.h" #include "measure.h" #include "pe.h" +#include "secure-boot.h" #include "splash.h" #include "util.h" /* magic string to find in the binary image */ static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-stub " GIT_VERSION " ####"; -static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE; - EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { EFI_LOADED_IMAGE *loaded_image; - _cleanup_freepool_ CHAR8 *b = NULL; - UINTN size; - BOOLEAN secure = FALSE; CHAR8 *sections[] = { (CHAR8 *)".cmdline", (CHAR8 *)".linux", @@ -46,10 +42,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { return err; } - if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS) - if (*b > 0) - secure = TRUE; - err = pe_memory_locate_sections(loaded_image->ImageBase, sections, addrs, offs, szs); if (EFI_ERROR(err)) { Print(L"Unable to locate embedded .linux section: %r ", err); @@ -63,7 +55,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { cmdline_len = szs[0]; /* if we are not in secure boot mode, or none was provided, accept a custom command line and replace the built-in one */ - if ((!secure || cmdline_len == 0) && loaded_image->LoadOptionsSize > 0 && *(CHAR16 *)loaded_image->LoadOptions > 0x1F) { + if ((!secure_boot_enabled() || cmdline_len == 0) && loaded_image->LoadOptionsSize > 0 && + *(CHAR16 *) loaded_image->LoadOptions > 0x1F) { CHAR16 *options; CHAR8 *line; UINTN i; From 50212228424532918182c53e5810835edbc1a328 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Sat, 30 Jan 2021 23:02:24 +0000 Subject: [PATCH 02/12] boot: Enable C99 Instead of using -nostdinc, we use -nostdlib. This is necessary to allow moving to C99 as efibind.h includes stdint.h when C99 is enabled. It isn't necessarily problematic to use some standard library headers as long as they don't contain functions defined in libc or another system library (or in other words, header only headers are fine to use in sd-boot). --- src/boot/efi/meson.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 875a501b30b..177957e76ac 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -134,8 +134,8 @@ endif if have_gnu_efi compile_args = ['-Wall', '-Wextra', - '-std=gnu90', - '-nostdinc', + '-std=gnu99', + '-nostdlib', '-fpic', '-fshort-wchar', '-ffreestanding', From 7d2ebb6f85cdeb0c4ddcdf08004f0547cad5cfe9 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Sat, 30 Jan 2021 23:10:13 +0000 Subject: [PATCH 03/12] boot: Turn all guid constants into C99 compound initializers Avoids having to use the address operator all the time and avoids having to cast or do other unintuitive stuff. --- src/boot/efi/boot.c | 24 ++++++++++-------------- src/boot/efi/console.c | 7 +++---- src/boot/efi/graphics.c | 8 ++++---- src/boot/efi/measure.c | 13 +++++++------ src/boot/efi/random-seed.c | 8 ++++---- src/boot/efi/secure-boot.c | 4 +--- src/boot/efi/shim.c | 22 ++++++++++++---------- src/boot/efi/stub.c | 10 +++++----- src/boot/efi/util.c | 11 ++--------- src/boot/efi/util.h | 9 ++++++++- 10 files changed, 56 insertions(+), 60 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 0d516e00dc5..c409f9d7f11 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -24,8 +24,6 @@ /* magic string to find in the binary image */ static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-boot " GIT_VERSION " ####"; -static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE; - enum loader_type { LOADER_UNDEFINED, LOADER_EFI, @@ -379,13 +377,13 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { Print(L"SecureBoot: %s\n", yes_no(secure_boot_enabled())); - if (efivar_get_raw(&global_guid, L"SetupMode", &modevar, &size) == EFI_SUCCESS) + if (efivar_get_raw(EFI_GLOBAL_GUID, L"SetupMode", &modevar, &size) == EFI_SUCCESS) Print(L"SetupMode: %s\n", *modevar > 0 ? L"setup" : L"user"); if (shim_loaded()) Print(L"Shim: present\n"); - if (efivar_get_raw(&global_guid, L"OsIndicationsSupported", &indvar, &size) == EFI_SUCCESS) + if (efivar_get_raw(EFI_GLOBAL_GUID, L"OsIndicationsSupported", &indvar, &size) == EFI_SUCCESS) Print(L"OsIndicationsSupported: %d\n", (UINT64)*indvar); Print(L"\n--- press key ---\n\n"); @@ -2020,10 +2018,8 @@ static VOID config_entry_add_linux( uefi_call_wrapper(linux_dir->Close, 1, linux_dir); } -/* Note that this is in GUID format, i.e. the first 32bit, and the following pair of 16bit are byteswapped. */ -static const UINT8 xbootldr_guid[16] = { - 0xff, 0xc2, 0x13, 0xbc, 0xe6, 0x59, 0x62, 0x42, 0xa3, 0x52, 0xb2, 0x75, 0xfd, 0x6f, 0x71, 0x72 -}; +#define XBOOTLDR_GUID \ + &(const EFI_GUID) { 0xbc13c2ff, 0x59e6, 0x4262, { 0xa3, 0x52, 0xb2, 0x75, 0xfd, 0x6f, 0x71, 0x72 } } static EFI_DEVICE_PATH *path_parent(EFI_DEVICE_PATH *path, EFI_DEVICE_PATH *node) { EFI_DEVICE_PATH *parent; @@ -2168,7 +2164,7 @@ static VOID config_load_xbootldr( entry = (EFI_PARTITION_ENTRY*) ((UINT8*) entries + h->SizeOfPartitionEntry * i); - if (CompareMem(&entry->PartitionTypeGUID, xbootldr_guid, 16) == 0) { + if (CompareMem(&entry->PartitionTypeGUID, XBOOTLDR_GUID, 16) == 0) { UINT64 end; /* Let's use memcpy(), in case the structs are not aligned (they really should be though) */ @@ -2297,11 +2293,11 @@ static EFI_STATUS reboot_into_firmware(VOID) { osind = EFI_OS_INDICATIONS_BOOT_TO_FW_UI; - err = efivar_get_raw(&global_guid, L"OsIndications", &b, &size); + err = efivar_get_raw(EFI_GLOBAL_GUID, L"OsIndications", &b, &size); if (!EFI_ERROR(err)) osind |= (UINT64)*b; - err = efivar_set_raw(&global_guid, L"OsIndications", &osind, sizeof(UINT64), TRUE); + err = efivar_set_raw(EFI_GLOBAL_GUID, L"OsIndications", &osind, sizeof(UINT64), TRUE); if (EFI_ERROR(err)) return err; @@ -2342,7 +2338,7 @@ static VOID config_write_entries_to_variable(Config *config) { } /* Store the full list of discovered entries. */ - (void) efivar_set_raw(&loader_guid, L"LoaderEntries", buffer, (UINT8*) p - (UINT8*) buffer, FALSE); + (void) efivar_set_raw(LOADER_GUID, L"LoaderEntries", buffer, (UINT8*) p - (UINT8*) buffer, FALSE); } EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { @@ -2379,7 +2375,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { typestr = PoolPrint(L"UEFI %d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); efivar_set(L"LoaderFirmwareType", typestr, FALSE); - (void) efivar_set_raw(&loader_guid, L"LoaderFeatures", &loader_features, sizeof(loader_features), FALSE); + (void) efivar_set_raw(LOADER_GUID, L"LoaderFeatures", &loader_features, sizeof(loader_features), FALSE); err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); @@ -2436,7 +2432,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { L"auto-efi-default", '\0', L"EFI Default Loader", L"\\EFI\\Boot\\boot" EFI_MACHINE_TYPE_NAME ".efi"); config_entry_add_osx(&config); - if (config.auto_firmware && efivar_get_raw(&global_guid, L"OsIndicationsSupported", &b, &size) == EFI_SUCCESS) { + if (config.auto_firmware && efivar_get_raw(EFI_GLOBAL_GUID, L"OsIndicationsSupported", &b, &size) == EFI_SUCCESS) { UINT64 osind = (UINT64)*b; if (osind & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) diff --git a/src/boot/efi/console.c b/src/boot/efi/console.c index 2dd4543d515..e3de27fee5c 100644 --- a/src/boot/efi/console.c +++ b/src/boot/efi/console.c @@ -9,8 +9,8 @@ #define SYSTEM_FONT_WIDTH 8 #define SYSTEM_FONT_HEIGHT 19 -#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \ - { 0xdd9e7534, 0x7762, 0x4698, { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } } +#define EFI_SIMPLE_TEXT_INPUT_EX_GUID \ + &(EFI_GUID) { 0xdd9e7534, 0x7762, 0x4698, { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } } struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL; @@ -67,7 +67,6 @@ typedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL { } EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL; EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait) { - EFI_GUID EfiSimpleTextInputExProtocolGuid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID; static EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx; static BOOLEAN checked; UINTN index; @@ -75,7 +74,7 @@ EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait) { EFI_STATUS err; if (!checked) { - err = LibLocateProtocol(&EfiSimpleTextInputExProtocolGuid, (VOID **)&TextInputEx); + err = LibLocateProtocol(EFI_SIMPLE_TEXT_INPUT_EX_GUID, (VOID **)&TextInputEx); if (EFI_ERROR(err)) TextInputEx = NULL; diff --git a/src/boot/efi/graphics.c b/src/boot/efi/graphics.c index f36ecb35b5b..ddfe68cc774 100644 --- a/src/boot/efi/graphics.c +++ b/src/boot/efi/graphics.c @@ -10,9 +10,10 @@ #include "graphics.h" #include "util.h" +#define EFI_CONSOLE_CONTROL_GUID \ + &(EFI_GUID) { 0xf42f7782, 0x12e, 0x4c12, { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } } + EFI_STATUS graphics_mode(BOOLEAN on) { - #define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \ - { 0xf42f7782, 0x12e, 0x4c12, { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } }; struct _EFI_CONSOLE_CONTROL_PROTOCOL; @@ -45,7 +46,6 @@ EFI_STATUS graphics_mode(BOOLEAN on) { EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn; } EFI_CONSOLE_CONTROL_PROTOCOL; - EFI_GUID ConsoleControlProtocolGuid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID; EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL; EFI_CONSOLE_CONTROL_SCREEN_MODE new; EFI_CONSOLE_CONTROL_SCREEN_MODE current; @@ -53,7 +53,7 @@ EFI_STATUS graphics_mode(BOOLEAN on) { BOOLEAN stdin_locked; EFI_STATUS err; - err = LibLocateProtocol(&ConsoleControlProtocolGuid, (VOID **)&ConsoleControl); + err = LibLocateProtocol(EFI_CONSOLE_CONTROL_GUID, (VOID **)&ConsoleControl); if (EFI_ERROR(err)) /* console control protocol is nonstandard and might not exist. */ return err == EFI_NOT_FOUND ? EFI_SUCCESS : err; diff --git a/src/boot/efi/measure.c b/src/boot/efi/measure.c index ff876a6c5b3..c272d085537 100644 --- a/src/boot/efi/measure.c +++ b/src/boot/efi/measure.c @@ -4,9 +4,11 @@ #include #include + #include "measure.h" -#define EFI_TCG_PROTOCOL_GUID { 0xf541796d, 0xa62e, 0x4954, {0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd} } +#define EFI_TCG_GUID \ + &(EFI_GUID) { 0xf541796d, 0xa62e, 0x4954, { 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd } } typedef struct _TCG_VERSION { UINT8 Major; @@ -100,7 +102,8 @@ typedef struct _EFI_TCG { EFI_TCG_HASH_LOG_EXTEND_EVENT HashLogExtendEvent; } EFI_TCG; -#define EFI_TCG2_PROTOCOL_GUID {0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f }} +#define EFI_TCG2_GUID \ + &(EFI_GUID) { 0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f } } typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL; @@ -238,7 +241,6 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32 } static EFI_TCG * tcg1_interface_check(void) { - EFI_GUID tpm_guid = EFI_TCG_PROTOCOL_GUID; EFI_STATUS status; EFI_TCG *tcg; TCG_BOOT_SERVICE_CAPABILITY capability; @@ -246,7 +248,7 @@ static EFI_TCG * tcg1_interface_check(void) { EFI_PHYSICAL_ADDRESS event_log_location; EFI_PHYSICAL_ADDRESS event_log_last_entry; - status = LibLocateProtocol(&tpm_guid, (void **) &tcg); + status = LibLocateProtocol(EFI_TCG_GUID, (void **) &tcg); if (EFI_ERROR(status)) return NULL; @@ -267,12 +269,11 @@ static EFI_TCG * tcg1_interface_check(void) { } static EFI_TCG2 * tcg2_interface_check(void) { - EFI_GUID tpm2_guid = EFI_TCG2_PROTOCOL_GUID; EFI_STATUS status; EFI_TCG2 *tcg; EFI_TCG2_BOOT_SERVICE_CAPABILITY capability; - status = LibLocateProtocol(&tpm2_guid, (void **) &tcg); + status = LibLocateProtocol(EFI_TCG2_GUID, (void **) &tcg); if (EFI_ERROR(status)) return NULL; diff --git a/src/boot/efi/random-seed.c b/src/boot/efi/random-seed.c index 18e686b3a80..b295b0b6bb1 100644 --- a/src/boot/efi/random-seed.c +++ b/src/boot/efi/random-seed.c @@ -12,7 +12,7 @@ #define RANDOM_MAX_SIZE_MIN (32U) #define RANDOM_MAX_SIZE_MAX (32U*1024U) -static const EFI_GUID rng_protocol_guid = EFI_RNG_PROTOCOL_GUID; +#define EFI_RNG_GUID &(EFI_GUID) EFI_RNG_PROTOCOL_GUID /* SHA256 gives us 256/8=32 bytes */ #define HASH_VALUE_SIZE 32 @@ -24,7 +24,7 @@ static EFI_STATUS acquire_rng(UINTN size, VOID **ret) { /* Try to acquire the specified number of bytes from the UEFI RNG */ - err = LibLocateProtocol((EFI_GUID*) &rng_protocol_guid, (VOID**) &rng); + err = LibLocateProtocol(EFI_RNG_GUID, (VOID**) &rng); if (EFI_ERROR(err)) return err; if (!rng) @@ -147,7 +147,7 @@ static EFI_STATUS acquire_system_token(VOID **ret, UINTN *ret_size) { EFI_STATUS err; UINTN size; - err = efivar_get_raw(&loader_guid, L"LoaderSystemToken", &data, &size); + err = efivar_get_raw(LOADER_GUID, L"LoaderSystemToken", &data, &size); if (EFI_ERROR(err)) { if (err != EFI_NOT_FOUND) Print(L"Failed to read LoaderSystemToken EFI variable: %r", err); @@ -318,7 +318,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) { } /* We are good to go */ - err = efivar_set_raw(&loader_guid, L"LoaderRandomSeed", for_kernel, size, FALSE); + err = efivar_set_raw(LOADER_GUID, L"LoaderRandomSeed", for_kernel, size, FALSE); if (EFI_ERROR(err)) { Print(L"Failed to write random seed to EFI variable: %r\n", err); return err; diff --git a/src/boot/efi/secure-boot.c b/src/boot/efi/secure-boot.c index cea7e288289..07d6252e27b 100644 --- a/src/boot/efi/secure-boot.c +++ b/src/boot/efi/secure-boot.c @@ -3,13 +3,11 @@ #include "secure-boot.h" #include "util.h" -static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE; - BOOLEAN secure_boot_enabled(void) { _cleanup_freepool_ CHAR8 *b = NULL; UINTN size; - if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS) + if (efivar_get_raw(EFI_GLOBAL_GUID, L"SecureBoot", &b, &size) == EFI_SUCCESS) return *b > 0; return FALSE; diff --git a/src/boot/efi/shim.c b/src/boot/efi/shim.c index 2039603260b..48602627bb7 100644 --- a/src/boot/efi/shim.c +++ b/src/boot/efi/shim.c @@ -30,16 +30,18 @@ struct ShimLock { EFI_STATUS __sysv_abi__ (*read_header) (VOID *data, UINT32 datasize, VOID *context); }; -static const EFI_GUID simple_fs_guid = SIMPLE_FILE_SYSTEM_PROTOCOL; - -static const EFI_GUID security_protocol_guid = { 0xa46423e3, 0x4617, 0x49f1, {0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39 } }; -static const EFI_GUID security2_protocol_guid = { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } }; -static const EFI_GUID shim_lock_guid = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }; +#define SIMPLE_FS_GUID &(EFI_GUID) SIMPLE_FILE_SYSTEM_PROTOCOL +#define SECURITY_PROTOCOL_GUID \ + &(EFI_GUID) { 0xa46423e3, 0x4617, 0x49f1, { 0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39 } } +#define SECURITY_PROTOCOL2_GUID \ + &(EFI_GUID) { 0x94ab2f58, 0x1438, 0x4ef1, { 0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } } +#define SHIM_LOCK_GUID \ + &(EFI_GUID) { 0x605dab50, 0xe046, 0x4300, { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } } BOOLEAN shim_loaded(void) { struct ShimLock *shim_lock; - return uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &shim_lock_guid, NULL, (VOID**) &shim_lock) == EFI_SUCCESS; + return uefi_call_wrapper(BS->LocateProtocol, 3, SHIM_LOCK_GUID, NULL, (VOID**) &shim_lock) == EFI_SUCCESS; } static BOOLEAN shim_validate(VOID *data, UINT32 size) { @@ -48,7 +50,7 @@ static BOOLEAN shim_validate(VOID *data, UINT32 size) { if (!data) return FALSE; - if (uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &shim_lock_guid, NULL, (VOID**) &shim_lock) != EFI_SUCCESS) + if (uefi_call_wrapper(BS->LocateProtocol, 3, SHIM_LOCK_GUID, NULL, (VOID**) &shim_lock) != EFI_SUCCESS) return FALSE; if (!shim_lock) @@ -146,7 +148,7 @@ static EFIAPI EFI_STATUS security_policy_authentication (const EFI_SECURITY_PROT dev_path = DuplicateDevicePath((EFI_DEVICE_PATH*) device_path_const); - status = uefi_call_wrapper(BS->LocateDevicePath, 3, (EFI_GUID*) &simple_fs_guid, &dev_path, &h); + status = uefi_call_wrapper(BS->LocateDevicePath, 3, SIMPLE_FS_GUID, &dev_path, &h); if (status != EFI_SUCCESS) return status; @@ -180,9 +182,9 @@ EFI_STATUS security_policy_install(void) { * to fail, since SECURITY2 was introduced in PI 1.2.1. * Use security2_protocol == NULL as indicator. */ - uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security2_protocol_guid, NULL, (VOID**) &security2_protocol); + uefi_call_wrapper(BS->LocateProtocol, 3, SECURITY_PROTOCOL2_GUID, NULL, (VOID**) &security2_protocol); - status = uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security_protocol_guid, NULL, (VOID**) &security_protocol); + status = uefi_call_wrapper(BS->LocateProtocol, 3, SECURITY_PROTOCOL_GUID, NULL, (VOID**) &security_protocol); /* This one is mandatory, so there's a serious problem */ if (status != EFI_SUCCESS) return status; diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index eb6ce61bb95..50e2dff7a19 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -81,12 +81,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { } /* Export the device path this image is started from, if it's not set yet */ - if (efivar_get_raw(&loader_guid, L"LoaderDevicePartUUID", NULL, NULL) != EFI_SUCCESS) + if (efivar_get_raw(LOADER_GUID, L"LoaderDevicePartUUID", NULL, NULL) != EFI_SUCCESS) if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS) efivar_set(L"LoaderDevicePartUUID", uuid, FALSE); /* if LoaderImageIdentifier is not set, assume the image with this stub was loaded directly from UEFI */ - if (efivar_get_raw(&loader_guid, L"LoaderImageIdentifier", NULL, NULL) != EFI_SUCCESS) { + if (efivar_get_raw(LOADER_GUID, L"LoaderImageIdentifier", NULL, NULL) != EFI_SUCCESS) { _cleanup_freepool_ CHAR16 *s; s = DevicePathToStr(loaded_image->FilePath); @@ -94,7 +94,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { } /* if LoaderFirmwareInfo is not set, let's set it */ - if (efivar_get_raw(&loader_guid, L"LoaderFirmwareInfo", NULL, NULL) != EFI_SUCCESS) { + if (efivar_get_raw(LOADER_GUID, L"LoaderFirmwareInfo", NULL, NULL) != EFI_SUCCESS) { _cleanup_freepool_ CHAR16 *s; s = PoolPrint(L"%s %d.%02d", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); @@ -102,7 +102,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { } /* ditto for LoaderFirmwareType */ - if (efivar_get_raw(&loader_guid, L"LoaderFirmwareType", NULL, NULL) != EFI_SUCCESS) { + if (efivar_get_raw(LOADER_GUID, L"LoaderFirmwareType", NULL, NULL) != EFI_SUCCESS) { _cleanup_freepool_ CHAR16 *s; s = PoolPrint(L"UEFI %d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); @@ -110,7 +110,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { } /* add StubInfo */ - if (efivar_get_raw(&loader_guid, L"StubInfo", NULL, NULL) != EFI_SUCCESS) + if (efivar_get_raw(LOADER_GUID, L"StubInfo", NULL, NULL) != EFI_SUCCESS) efivar_set(L"StubInfo", L"systemd-stub " GIT_VERSION, FALSE); if (szs[3] > 0) diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index 2712c2d3f0e..0c924b57da6 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -5,13 +5,6 @@ #include "util.h" -/* - * Allocated random UUID, intended to be shared across tools that implement - * the (ESP)\loader\entries\-.conf convention and the - * associated EFI variables. - */ -const EFI_GUID loader_guid = { 0x4a67b082, 0x0a4c, 0x41cf, {0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f} }; - #ifdef __x86_64__ UINT64 ticks_read(VOID) { UINT64 a, d; @@ -93,7 +86,7 @@ EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const VOID } EFI_STATUS efivar_set(const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent) { - return efivar_set_raw(&loader_guid, name, value, value ? (StrLen(value)+1) * sizeof(CHAR16) : 0, persistent); + return efivar_set_raw(LOADER_GUID, name, value, value ? (StrLen(value)+1) * sizeof(CHAR16) : 0, persistent); } EFI_STATUS efivar_set_int(CHAR16 *name, UINTN i, BOOLEAN persistent) { @@ -109,7 +102,7 @@ EFI_STATUS efivar_get(const CHAR16 *name, CHAR16 **value) { CHAR16 *val; UINTN size; - err = efivar_get_raw(&loader_guid, name, &buf, &size); + err = efivar_get_raw(LOADER_GUID, name, &buf, &size); if (EFI_ERROR(err)) return err; diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index 916519cdf83..f0a645b832a 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -55,7 +55,14 @@ static inline void FileHandleClosep(EFI_FILE_HANDLE *handle) { uefi_call_wrapper((*handle)->Close, 1, *handle); } -extern const EFI_GUID loader_guid; +/* + * Allocated random UUID, intended to be shared across tools that implement + * the (ESP)\loader\entries\-.conf convention and the + * associated EFI variables. + */ +#define LOADER_GUID \ + &(const EFI_GUID) { 0x4a67b082, 0x0a4c, 0x41cf, { 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } } +#define EFI_GLOBAL_GUID &(const EFI_GUID) EFI_GLOBAL_VARIABLE #define UINTN_MAX (~(UINTN)0) #define INTN_MAX ((INTN)(UINTN_MAX>>1)) From 5e1f0e6fca28bd26de5b1afb684e6ebb5b516585 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Sat, 30 Jan 2021 23:25:24 +0000 Subject: [PATCH 04/12] boot: Make all efivar util functions take the guid as an argument Let's make these functions a little more generic so we can have them work on more than one GUID. More specifically, this allows using them with the global guid which will be used a bit more to extend the secure boot support. --- src/boot/efi/boot.c | 53 +++++++++++++++++++++++++-------------------- src/boot/efi/stub.c | 10 ++++----- src/boot/efi/util.c | 21 +++++++++--------- src/boot/efi/util.h | 10 ++++----- 4 files changed, 50 insertions(+), 44 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index c409f9d7f11..3804061ff33 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -421,14 +421,14 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { Print(L"entry EFI var idx: %d\n", config->idx_default_efivar); Print(L"\n"); - if (efivar_get_int(L"LoaderConfigTimeout", &i) == EFI_SUCCESS) + if (efivar_get_int(LOADER_GUID, L"LoaderConfigTimeout", &i) == EFI_SUCCESS) Print(L"LoaderConfigTimeout: %u\n", i); if (config->entry_oneshot) Print(L"LoaderEntryOneShot: %s\n", config->entry_oneshot); - if (efivar_get(L"LoaderDevicePartUUID", &partstr) == EFI_SUCCESS) + if (efivar_get(LOADER_GUID, L"LoaderDevicePartUUID", &partstr) == EFI_SUCCESS) Print(L"LoaderDevicePartUUID: %s\n", partstr); - if (efivar_get(L"LoaderEntryDefault", &defaultstr) == EFI_SUCCESS) + if (efivar_get(LOADER_GUID, L"LoaderEntryDefault", &defaultstr) == EFI_SUCCESS) Print(L"LoaderEntryDefault: %s\n", defaultstr); Print(L"\n--- press key ---\n\n"); @@ -762,12 +762,16 @@ static BOOLEAN menu_run( case KEYPRESS(0, 0, 'd'): if (config->idx_default_efivar != (INTN)idx_highlight) { /* store the selected entry in a persistent EFI variable */ - efivar_set(L"LoaderEntryDefault", config->entries[idx_highlight]->id, TRUE); + efivar_set( + LOADER_GUID, + L"LoaderEntryDefault", + config->entries[idx_highlight]->id, + TRUE); config->idx_default_efivar = idx_highlight; status = StrDuplicate(L"Default boot entry selected."); } else { /* clear the default entry EFI variable */ - efivar_set(L"LoaderEntryDefault", NULL, TRUE); + efivar_set(LOADER_GUID, L"LoaderEntryDefault", NULL, TRUE); config->idx_default_efivar = -1; status = StrDuplicate(L"Default boot entry cleared."); } @@ -778,14 +782,15 @@ static BOOLEAN menu_run( case KEYPRESS(0, 0, 'T'): if (config->timeout_sec_efivar > 0) { config->timeout_sec_efivar--; - efivar_set_int(L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE); + efivar_set_int( + LOADER_GUID, L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE); if (config->timeout_sec_efivar > 0) status = PoolPrint(L"Menu timeout set to %d sec.", config->timeout_sec_efivar); else status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu."); } else if (config->timeout_sec_efivar <= 0){ config->timeout_sec_efivar = -1; - efivar_set(L"LoaderConfigTimeout", NULL, TRUE); + efivar_set(LOADER_GUID, L"LoaderConfigTimeout", NULL, TRUE); if (config->timeout_sec_config > 0) status = PoolPrint(L"Menu timeout of %d sec is defined by configuration file.", config->timeout_sec_config); @@ -799,7 +804,7 @@ static BOOLEAN menu_run( if (config->timeout_sec_efivar == -1 && config->timeout_sec_config == 0) config->timeout_sec_efivar++; config->timeout_sec_efivar++; - efivar_set_int(L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE); + efivar_set_int(LOADER_GUID, L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE); if (config->timeout_sec_efivar > 0) status = PoolPrint(L"Menu timeout set to %d sec.", config->timeout_sec_efivar); @@ -1291,7 +1296,7 @@ static VOID config_entry_bump_counters( /* Let's tell the OS that we renamed this file, so that it knows what to rename to the counter-less name on * success */ new_path = PoolPrint(L"%s\\%s", entry->path, entry->next_name); - efivar_set(L"LoaderBootCountPath", new_path, FALSE); + efivar_set(LOADER_GUID, L"LoaderBootCountPath", new_path, FALSE); /* If the file we just renamed is the loader path, then let's update that. */ if (StrCmp(entry->loader, old_path) == 0) { @@ -1456,17 +1461,17 @@ static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) { if (!EFI_ERROR(err)) config_defaults_load_from_file(config, content); - err = efivar_get_int(L"LoaderConfigTimeout", &sec); + err = efivar_get_int(LOADER_GUID, L"LoaderConfigTimeout", &sec); if (!EFI_ERROR(err)) { config->timeout_sec_efivar = sec > INTN_MAX ? INTN_MAX : sec; config->timeout_sec = sec; } else config->timeout_sec_efivar = -1; - err = efivar_get_int(L"LoaderConfigTimeoutOneShot", &sec); + err = efivar_get_int(LOADER_GUID, L"LoaderConfigTimeoutOneShot", &sec); if (!EFI_ERROR(err)) { /* Unset variable now, after all it's "one shot". */ - (void) efivar_set(L"LoaderConfigTimeoutOneShot", NULL, TRUE); + (void) efivar_set(LOADER_GUID, L"LoaderConfigTimeoutOneShot", NULL, TRUE); config->timeout_sec = sec; config->force_menu = TRUE; /* force the menu when this is set */ @@ -1593,11 +1598,11 @@ static VOID config_default_entry_select(Config *config) { * The EFI variable to specify a boot entry for the next, and only the * next reboot. The variable is always cleared directly after it is read. */ - err = efivar_get(L"LoaderEntryOneShot", &entry_oneshot); + err = efivar_get(LOADER_GUID, L"LoaderEntryOneShot", &entry_oneshot); if (!EFI_ERROR(err)) { config->entry_oneshot = StrDuplicate(entry_oneshot); - efivar_set(L"LoaderEntryOneShot", NULL, TRUE); + efivar_set(LOADER_GUID, L"LoaderEntryOneShot", NULL, TRUE); i = config_entry_find(config, entry_oneshot); if (i >= 0) { @@ -1612,7 +1617,7 @@ static VOID config_default_entry_select(Config *config) { * the 'd' key in the loader selection menu, the entry is marked with * an '*'. */ - err = efivar_get(L"LoaderEntryDefault", &entry_default); + err = efivar_get(LOADER_GUID, L"LoaderEntryDefault", &entry_default); if (!EFI_ERROR(err)) { i = config_entry_find(config, entry_default); @@ -2278,7 +2283,7 @@ static EFI_STATUS image_start( #endif } - efivar_set_time_usec(L"LoaderTimeExecUSec", 0); + efivar_set_time_usec(LOADER_GUID, L"LoaderTimeExecUSec", 0); err = uefi_call_wrapper(BS->StartImage, 3, image, NULL, NULL); out_unload: uefi_call_wrapper(BS->UnloadImage, 1, image); @@ -2366,14 +2371,14 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { InitializeLib(image, sys_table); init_usec = time_usec(); - efivar_set_time_usec(L"LoaderTimeInitUSec", init_usec); - efivar_set(L"LoaderInfo", L"systemd-boot " GIT_VERSION, FALSE); + efivar_set_time_usec(LOADER_GUID, L"LoaderTimeInitUSec", init_usec); + efivar_set(LOADER_GUID, L"LoaderInfo", L"systemd-boot " GIT_VERSION, FALSE); infostr = PoolPrint(L"%s %d.%02d", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); - efivar_set(L"LoaderFirmwareInfo", infostr, FALSE); + efivar_set(LOADER_GUID, L"LoaderFirmwareInfo", infostr, FALSE); typestr = PoolPrint(L"UEFI %d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); - efivar_set(L"LoaderFirmwareType", typestr, FALSE); + efivar_set(LOADER_GUID, L"LoaderFirmwareType", typestr, FALSE); (void) efivar_set_raw(LOADER_GUID, L"LoaderFeatures", &loader_features, sizeof(loader_features), FALSE); @@ -2387,7 +2392,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { /* export the device path this image is started from */ if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS) - efivar_set(L"LoaderDevicePartUUID", uuid, FALSE); + efivar_set(LOADER_GUID, L"LoaderDevicePartUUID", uuid, FALSE); root_dir = LibOpenRoot(loaded_image->DeviceHandle); if (!root_dir) { @@ -2407,7 +2412,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { /* the filesystem path to this image, to prevent adding ourselves to the menu */ loaded_image_path = DevicePathToStr(loaded_image->FilePath); - efivar_set(L"LoaderImageIdentifier", loaded_image_path, FALSE); + efivar_set(LOADER_GUID, L"LoaderImageIdentifier", loaded_image_path, FALSE); config_load_defaults(&config, root_dir); @@ -2493,7 +2498,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { entry = config.entries[config.idx_default]; if (menu) { - efivar_set_time_usec(L"LoaderTimeMenuUSec", 0); + efivar_set_time_usec(LOADER_GUID, L"LoaderTimeMenuUSec", 0); uefi_call_wrapper(BS->SetWatchdogTimer, 4, 0, 0x10000, 0, NULL); if (!menu_run(&config, &entry, loaded_image_path)) break; @@ -2508,7 +2513,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { config_entry_bump_counters(entry, root_dir); /* Export the selected boot entry to the system */ - (VOID) efivar_set(L"LoaderEntrySelected", entry->id, FALSE); + (VOID) efivar_set(LOADER_GUID, L"LoaderEntrySelected", entry->id, FALSE); /* Optionally, read a random seed off the ESP and pass it to the OS */ (VOID) process_random_seed(root_dir, config.random_seed_mode); diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index 50e2dff7a19..2dffa4138ad 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -83,14 +83,14 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { /* Export the device path this image is started from, if it's not set yet */ if (efivar_get_raw(LOADER_GUID, L"LoaderDevicePartUUID", NULL, NULL) != EFI_SUCCESS) if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS) - efivar_set(L"LoaderDevicePartUUID", uuid, FALSE); + efivar_set(LOADER_GUID, L"LoaderDevicePartUUID", uuid, FALSE); /* if LoaderImageIdentifier is not set, assume the image with this stub was loaded directly from UEFI */ if (efivar_get_raw(LOADER_GUID, L"LoaderImageIdentifier", NULL, NULL) != EFI_SUCCESS) { _cleanup_freepool_ CHAR16 *s; s = DevicePathToStr(loaded_image->FilePath); - efivar_set(L"LoaderImageIdentifier", s, FALSE); + efivar_set(LOADER_GUID, L"LoaderImageIdentifier", s, FALSE); } /* if LoaderFirmwareInfo is not set, let's set it */ @@ -98,7 +98,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { _cleanup_freepool_ CHAR16 *s; s = PoolPrint(L"%s %d.%02d", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff); - efivar_set(L"LoaderFirmwareInfo", s, FALSE); + efivar_set(LOADER_GUID, L"LoaderFirmwareInfo", s, FALSE); } /* ditto for LoaderFirmwareType */ @@ -106,12 +106,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { _cleanup_freepool_ CHAR16 *s; s = PoolPrint(L"UEFI %d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); - efivar_set(L"LoaderFirmwareType", s, FALSE); + efivar_set(LOADER_GUID, L"LoaderFirmwareType", s, FALSE); } /* add StubInfo */ if (efivar_get_raw(LOADER_GUID, L"StubInfo", NULL, NULL) != EFI_SUCCESS) - efivar_set(L"StubInfo", L"systemd-stub " GIT_VERSION, FALSE); + efivar_set(LOADER_GUID, L"StubInfo", L"systemd-stub " GIT_VERSION, FALSE); if (szs[3] > 0) graphics_splash((UINT8 *)((UINTN)loaded_image->ImageBase + addrs[3]), szs[3], NULL); diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index 0c924b57da6..c795bd6dbc4 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -85,24 +85,25 @@ EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const VOID return uefi_call_wrapper(RT->SetVariable, 5, (CHAR16*) name, (EFI_GUID *)vendor, flags, size, (VOID*) buf); } -EFI_STATUS efivar_set(const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent) { - return efivar_set_raw(LOADER_GUID, name, value, value ? (StrLen(value)+1) * sizeof(CHAR16) : 0, persistent); +EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent) { + return efivar_set_raw( + vendor, name, value, value ? (StrLen(value) + 1) * sizeof(CHAR16) : 0, persistent); } -EFI_STATUS efivar_set_int(CHAR16 *name, UINTN i, BOOLEAN persistent) { +EFI_STATUS efivar_set_int(const EFI_GUID *vendor, CHAR16 *name, UINTN i, BOOLEAN persistent) { CHAR16 str[32]; SPrint(str, 32, L"%u", i); - return efivar_set(name, str, persistent); + return efivar_set(vendor, name, str, persistent); } -EFI_STATUS efivar_get(const CHAR16 *name, CHAR16 **value) { +EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value) { _cleanup_freepool_ CHAR8 *buf = NULL; EFI_STATUS err; CHAR16 *val; UINTN size; - err = efivar_get_raw(LOADER_GUID, name, &buf, &size); + err = efivar_get_raw(vendor, name, &buf, &size); if (EFI_ERROR(err)) return err; @@ -131,11 +132,11 @@ EFI_STATUS efivar_get(const CHAR16 *name, CHAR16 **value) { return EFI_SUCCESS; } -EFI_STATUS efivar_get_int(const CHAR16 *name, UINTN *i) { +EFI_STATUS efivar_get_int(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i) { _cleanup_freepool_ CHAR16 *val = NULL; EFI_STATUS err; - err = efivar_get(name, &val); + err = efivar_get(vendor, name, &val); if (!EFI_ERROR(err) && i) *i = Atoi(val); @@ -165,7 +166,7 @@ EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **bu return err; } -VOID efivar_set_time_usec(CHAR16 *name, UINT64 usec) { +VOID efivar_set_time_usec(const EFI_GUID *vendor, CHAR16 *name, UINT64 usec) { CHAR16 str[32]; if (usec == 0) @@ -174,7 +175,7 @@ VOID efivar_set_time_usec(CHAR16 *name, UINT64 usec) { return; SPrint(str, 32, L"%ld", usec); - efivar_set(name, str, FALSE); + efivar_set(vendor, name, str, FALSE); } static INTN utf8_to_16(CHAR8 *stra, CHAR16 *c) { diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index f0a645b832a..92c3a0a5848 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -21,14 +21,14 @@ UINT64 ticks_read(void); UINT64 ticks_freq(void); UINT64 time_usec(void); -EFI_STATUS efivar_set(const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent); +EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent); EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const VOID *buf, UINTN size, BOOLEAN persistent); -EFI_STATUS efivar_set_int(CHAR16 *name, UINTN i, BOOLEAN persistent); -VOID efivar_set_time_usec(CHAR16 *name, UINT64 usec); +EFI_STATUS efivar_set_int(const EFI_GUID *vendor, CHAR16 *name, UINTN i, BOOLEAN persistent); +VOID efivar_set_time_usec(const EFI_GUID *vendor, CHAR16 *name, UINT64 usec); -EFI_STATUS efivar_get(const CHAR16 *name, CHAR16 **value); +EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value); EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size); -EFI_STATUS efivar_get_int(const CHAR16 *name, UINTN *i); +EFI_STATUS efivar_get_int(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i); CHAR8 *strchra(CHAR8 *s, CHAR8 c); CHAR16 *stra_to_path(CHAR8 *stra); From 2a7c16753bcebbe149ec20477a6fff66e8f7a1b4 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Sun, 31 Jan 2021 10:56:21 +0000 Subject: [PATCH 05/12] boot: Add efivar_get_boolean_u8() --- src/boot/efi/secure-boot.c | 9 ++++----- src/boot/efi/util.c | 12 ++++++++++++ src/boot/efi/util.h | 1 + 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/boot/efi/secure-boot.c b/src/boot/efi/secure-boot.c index 07d6252e27b..cacf3b6a7b8 100644 --- a/src/boot/efi/secure-boot.c +++ b/src/boot/efi/secure-boot.c @@ -4,11 +4,10 @@ #include "util.h" BOOLEAN secure_boot_enabled(void) { - _cleanup_freepool_ CHAR8 *b = NULL; - UINTN size; + BOOLEAN secure; + EFI_STATUS err; - if (efivar_get_raw(EFI_GLOBAL_GUID, L"SecureBoot", &b, &size) == EFI_SUCCESS) - return *b > 0; + err = efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SecureBoot", &secure); - return FALSE; + return !EFI_ERROR(err) && secure; } diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index c795bd6dbc4..9019cd7a252 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -166,6 +166,18 @@ EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **bu return err; } +EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOOLEAN *ret) { + _cleanup_freepool_ CHAR8 *b = NULL; + UINTN size; + EFI_STATUS err; + + err = efivar_get_raw(vendor, name, &b, &size); + if (!EFI_ERROR(err)) + *ret = *b > 0; + + return err; +} + VOID efivar_set_time_usec(const EFI_GUID *vendor, CHAR16 *name, UINT64 usec) { CHAR16 str[32]; diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index 92c3a0a5848..07882383d4d 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -29,6 +29,7 @@ VOID efivar_set_time_usec(const EFI_GUID *vendor, CHAR16 *name, UINT64 usec); EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value); EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size); EFI_STATUS efivar_get_int(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i); +EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOOLEAN *ret); CHAR8 *strchra(CHAR8 *s, CHAR8 c); CHAR16 *stra_to_path(CHAR8 *stra); From 258f0970f96d44057cd456bb3b9fb2c9114030f2 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 1 Feb 2021 22:31:47 +0000 Subject: [PATCH 06/12] boot: Tighten scope of variables used in loops --- src/boot/efi/boot.c | 125 ++++++++++++++++--------------------- src/boot/efi/crc32.c | 3 +- src/boot/efi/disk.c | 3 +- src/boot/efi/pe.c | 6 +- src/boot/efi/random-seed.c | 7 +-- src/boot/efi/sha256.c | 11 ++-- src/boot/efi/splash.c | 10 +-- src/boot/efi/stub.c | 3 +- src/boot/efi/util.c | 3 +- 9 files changed, 70 insertions(+), 101 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 3804061ff33..da3bd119754 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -118,17 +118,17 @@ static BOOLEAN line_edit( while (!exit) { EFI_STATUS err; UINT64 key; - UINTN i; + UINTN j; - i = len - first; - if (i >= x_max-1) - i = x_max-1; - CopyMem(print, line + first, i * sizeof(CHAR16)); - while (clear > 0 && i < x_max-1) { + j = len - first; + if (j >= x_max-1) + j = x_max-1; + CopyMem(print, line + first, j * sizeof(CHAR16)); + while (clear > 0 && j < x_max-1) { clear--; - print[i++] = ' '; + print[j++] = ' '; } - print[i] = '\0'; + print[j] = '\0'; uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0, y_pos); uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, print); @@ -212,12 +212,14 @@ static BOOLEAN line_edit( case KEYPRESS(EFI_ALT_PRESSED, 0, 'd'): /* kill-word */ clear = 0; - for (i = first + cursor; i < len && line[i] == ' '; i++) + + UINTN k; + for (k = first + cursor; k < len && line[k] == ' '; k++) clear++; - for (; i < len && line[i] != ' '; i++) + for (; k < len && line[k] != ' '; k++) clear++; - for (i = first + cursor; i + clear < len; i++) + for (UINTN i = first + cursor; i + clear < len; i++) line[i] = line[i + clear]; len -= clear; line[len] = '\0'; @@ -242,7 +244,7 @@ static BOOLEAN line_edit( } uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, cursor, y_pos); - for (i = first + cursor; i + clear < len; i++) + for (UINTN i = first + cursor; i + clear < len; i++) line[i] = line[i + clear]; len -= clear; line[len] = '\0'; @@ -255,7 +257,7 @@ static BOOLEAN line_edit( continue; if (first + cursor == len) continue; - for (i = first + cursor; i < len; i++) + for (UINTN i = first + cursor; i < len; i++) line[i] = line[i+1]; clear = 1; len--; @@ -284,7 +286,7 @@ static BOOLEAN line_edit( continue; if (first == 0 && cursor == 0) continue; - for (i = first + cursor-1; i < len; i++) + for (UINTN i = first + cursor-1; i < len; i++) line[i] = line[i+1]; clear = 1; len--; @@ -312,7 +314,7 @@ static BOOLEAN line_edit( case KEYPRESS(0, 0, 0x80) ... KEYPRESS(0, 0, 0xffff): if (len+1 == size) continue; - for (i = len; i > first + cursor; i--) + for (UINTN i = len; i > first + cursor; i--) line[i] = line[i-1]; line[first + cursor] = KEYCHAR(key); len++; @@ -330,25 +332,23 @@ static BOOLEAN line_edit( } static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) { - UINTN i; - if (key == 0) return -1; /* select entry by number key */ if (key >= '1' && key <= '9') { - i = key - '0'; + UINTN i = key - '0'; if (i > config->entry_count) i = config->entry_count; return i-1; } /* find matching key in config entries */ - for (i = start; i < config->entry_count; i++) + for (UINTN i = start; i < config->entry_count; i++) if (config->entries[i]->key == key) return i; - for (i = 0; i < start; i++) + for (UINTN i = 0; i < start; i++) if (config->entries[i]->key == key) return i; @@ -357,7 +357,7 @@ static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) { static VOID print_status(Config *config, CHAR16 *loaded_image_path) { UINT64 key; - UINTN i; + UINTN timeout; _cleanup_freepool_ CHAR8 *modevar = NULL, *indvar = NULL; _cleanup_freepool_ CHAR16 *partstr = NULL, *defaultstr = NULL; UINTN x, y, size; @@ -421,8 +421,8 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { Print(L"entry EFI var idx: %d\n", config->idx_default_efivar); Print(L"\n"); - if (efivar_get_int(LOADER_GUID, L"LoaderConfigTimeout", &i) == EFI_SUCCESS) - Print(L"LoaderConfigTimeout: %u\n", i); + if (efivar_get_int(LOADER_GUID, L"LoaderConfigTimeout", &timeout) == EFI_SUCCESS) + Print(L"LoaderConfigTimeout: %u\n", timeout); if (config->entry_oneshot) Print(L"LoaderEntryOneShot: %s\n", config->entry_oneshot); @@ -434,7 +434,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { Print(L"\n--- press key ---\n\n"); console_key_read(&key, TRUE); - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { ConfigEntry *entry; if (key == KEYPRESS(0, SCAN_ESC, 0) || key == KEYPRESS(0, 0, 'q')) @@ -501,7 +501,6 @@ static BOOLEAN menu_run( UINTN idx_last; BOOLEAN refresh; BOOLEAN highlight; - UINTN i; UINTN line_width; CHAR16 **lines; UINTN x_start; @@ -562,7 +561,7 @@ static BOOLEAN menu_run( /* length of the longest entry */ line_width = 5; - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { UINTN entry_len; entry_len = StrLen(config->entries[i]->title_show); @@ -581,14 +580,14 @@ static BOOLEAN menu_run( /* menu entries title lines */ lines = AllocatePool(sizeof(CHAR16 *) * config->entry_count); - for (i = 0; i < config->entry_count; i++) { - UINTN j, k; + for (UINTN i = 0; i < config->entry_count; i++) { + UINTN j; lines[i] = AllocatePool(((x_max+1) * sizeof(CHAR16))); for (j = 0; j < x_start; j++) lines[i][j] = ' '; - for (k = 0; config->entries[i]->title_show[k] != '\0' && j < x_max; j++, k++) + for (UINTN k = 0; config->entries[i]->title_show[k] != '\0' && j < x_max; j++, k++) lines[i][j] = config->entries[i]->title_show[k]; for (; j < x_max; j++) @@ -598,15 +597,15 @@ static BOOLEAN menu_run( status = NULL; clearline = AllocatePool((x_max+1) * sizeof(CHAR16)); - for (i = 0; i < x_max; i++) + for (UINTN i = 0; i < x_max; i++) clearline[i] = ' '; - clearline[i] = 0; + clearline[x_max] = 0; while (!exit) { UINT64 key; if (refresh) { - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { if (i < idx_first || i > idx_last) continue; uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0, y_start + i - idx_first); @@ -866,7 +865,7 @@ static BOOLEAN menu_run( *chosen_entry = config->entries[idx_highlight]; - for (i = 0; i < config->entry_count; i++) + for (UINTN i = 0; i < config->entry_count; i++) FreePool(lines[i]); FreePool(lines); FreePool(clearline); @@ -1556,14 +1555,11 @@ static INTN config_entry_compare(ConfigEntry *a, ConfigEntry *b) { } static VOID config_sort_entries(Config *config) { - UINTN i; - - for (i = 1; i < config->entry_count; i++) { + for (UINTN i = 1; i < config->entry_count; i++) { BOOLEAN more; - UINTN k; more = FALSE; - for (k = 0; k < config->entry_count - i; k++) { + for (UINTN k = 0; k < config->entry_count - i; k++) { ConfigEntry *entry; if (config_entry_compare(config->entries[k], config->entries[k+1]) <= 0) @@ -1580,9 +1576,7 @@ static VOID config_sort_entries(Config *config) { } static INTN config_entry_find(Config *config, CHAR16 *id) { - UINTN i; - - for (i = 0; i < config->entry_count; i++) + for (UINTN i = 0; i < config->entry_count; i++) if (StrCmp(config->entries[i]->id, id) == 0) return (INTN) i; @@ -1663,13 +1657,12 @@ static VOID config_default_entry_select(Config *config) { static BOOLEAN find_nonunique(ConfigEntry **entries, UINTN entry_count) { BOOLEAN non_unique = FALSE; - UINTN i, k; - for (i = 0; i < entry_count; i++) + for (UINTN i = 0; i < entry_count; i++) entries[i]->non_unique = FALSE; - for (i = 0; i < entry_count; i++) - for (k = 0; k < entry_count; k++) { + for (UINTN i = 0; i < entry_count; i++) + for (UINTN k = 0; k < entry_count; k++) { if (i == k) continue; if (StrCmp(entries[i]->title_show, entries[k]->title_show) != 0) @@ -1683,10 +1676,8 @@ static BOOLEAN find_nonunique(ConfigEntry **entries, UINTN entry_count) { /* generate a unique title, avoiding non-distinguishable menu entries */ static VOID config_title_generate(Config *config) { - UINTN i; - /* set title */ - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { CHAR16 *title; FreePool(config->entries[i]->title_show); @@ -1700,7 +1691,7 @@ static VOID config_title_generate(Config *config) { return; /* add version to non-unique titles */ - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { CHAR16 *s; if (!config->entries[i]->non_unique) @@ -1717,7 +1708,7 @@ static VOID config_title_generate(Config *config) { return; /* add machine-id to non-unique titles */ - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { CHAR16 *s; _cleanup_freepool_ CHAR16 *m = NULL; @@ -1737,7 +1728,7 @@ static VOID config_title_generate(Config *config) { return; /* add file name to non-unique titles */ - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { CHAR16 *s; if (!config->entries[i]->non_unique) @@ -1830,10 +1821,7 @@ static BOOLEAN config_entry_add_loader_auto( /* look for systemd-boot magic string */ err = file_read(root_dir, loader, 0, 100*1024, &content, &len); if (!EFI_ERROR(err)) { - CHAR8 *start = content; - CHAR8 *last = content + len - sizeof(magic) - 1; - - for (; start <= last; start++) + for (CHAR8 *start = content; start <= content + len - sizeof(magic) - 1; start++) if (start[0] == magic[0] && CompareMem(start, magic, sizeof(magic) - 1) == 0) return FALSE; } @@ -1865,9 +1853,7 @@ static VOID config_entry_add_osx(Config *config) { err = LibLocateHandle(ByProtocol, &FileSystemProtocol, NULL, &handle_count, &handles); if (!EFI_ERROR(err)) { - UINTN i; - - for (i = 0; i < handle_count; i++) { + for (UINTN i = 0; i < handle_count; i++) { EFI_FILE *root; BOOLEAN found; @@ -2042,7 +2028,7 @@ static VOID config_load_xbootldr( Config *config, EFI_HANDLE *device) { - EFI_DEVICE_PATH *partition_path, *node, *disk_path, *copy; + EFI_DEVICE_PATH *partition_path, *disk_path, *copy; UINT32 found_partition_number = (UINT32) -1; UINT64 found_partition_start = (UINT64) -1; UINT64 found_partition_size = (UINT64) -1; @@ -2055,11 +2041,10 @@ static VOID config_load_xbootldr( if (!partition_path) return; - for (node = partition_path; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) { + for (EFI_DEVICE_PATH *node = partition_path; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) { EFI_HANDLE disk_handle; EFI_BLOCK_IO *block_io; EFI_DEVICE_PATH *p; - UINTN nr; /* First, Let's look for the SCSI/SATA/USB/… device path node, i.e. one above the media * devices */ @@ -2086,7 +2071,7 @@ static VOID config_load_xbootldr( continue; /* Try both copies of the GPT header, in case one is corrupted */ - for (nr = 0; nr < 2; nr++) { + for (UINTN nr = 0; nr < 2; nr++) { _cleanup_freepool_ EFI_PARTITION_ENTRY* entries = NULL; union { EFI_PARTITION_TABLE_HEADER gpt_header; @@ -2094,7 +2079,7 @@ static VOID config_load_xbootldr( } gpt_header_buffer; const EFI_PARTITION_TABLE_HEADER *h = &gpt_header_buffer.gpt_header; UINT64 where; - UINTN i, sz; + UINTN sz; UINT32 c; if (nr == 0) @@ -2164,7 +2149,7 @@ static VOID config_load_xbootldr( if (c != h->PartitionEntryArrayCRC32) continue; - for (i = 0; i < h->NumberOfPartitionEntries; i++) { + for (UINTN i = 0; i < h->NumberOfPartitionEntries; i++) { EFI_PARTITION_ENTRY *entry; entry = (EFI_PARTITION_ENTRY*) ((UINT8*) entries + h->SizeOfPartitionEntry * i); @@ -2198,7 +2183,7 @@ found: copy = DuplicateDevicePath(partition_path); /* Patch in the data we found */ - for (node = copy; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) { + for (EFI_DEVICE_PATH *node = copy; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) { HARDDRIVE_DEVICE_PATH *hd; if (DevicePathType(node) != MEDIA_DEVICE_PATH) @@ -2313,9 +2298,7 @@ static EFI_STATUS reboot_into_firmware(VOID) { } static VOID config_free(Config *config) { - UINTN i; - - for (i = 0; i < config->entry_count; i++) + for (UINTN i = 0; i < config->entry_count; i++) config_entry_free(config->entries[i]); FreePool(config->entries); FreePool(config->entry_default_pattern); @@ -2325,15 +2308,15 @@ static VOID config_free(Config *config) { static VOID config_write_entries_to_variable(Config *config) { _cleanup_freepool_ CHAR16 *buffer = NULL; - UINTN i, sz = 0; + UINTN sz = 0; CHAR16 *p; - for (i = 0; i < config->entry_count; i++) + for (UINTN i = 0; i < config->entry_count; i++) sz += StrLen(config->entries[i]->id) + 1; p = buffer = AllocatePool(sz * sizeof(CHAR16)); - for (i = 0; i < config->entry_count; i++) { + for (UINTN i = 0; i < config->entry_count; i++) { UINTN l; l = StrLen(config->entries[i]->id) + 1; diff --git a/src/boot/efi/crc32.c b/src/boot/efi/crc32.c index 5dfd3db265f..c9e5501ffa7 100644 --- a/src/boot/efi/crc32.c +++ b/src/boot/efi/crc32.c @@ -128,9 +128,8 @@ UINT32 crc32_exclude_offset( const UINT8 *p = buf; UINT32 crc = seed; - UINTN i; - for (i = 0; i < len; i++) { + for (UINTN i = 0; i < len; i++) { UINT8 x = *p++; if (i >= exclude_off && i < exclude_off + exclude_len) diff --git a/src/boot/efi/disk.c b/src/boot/efi/disk.c index cc752956c34..122f08dd5cd 100644 --- a/src/boot/efi/disk.c +++ b/src/boot/efi/disk.c @@ -13,10 +13,9 @@ EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, CHAR16 uuid[static 37]) { device_path = DevicePathFromHandle(handle); if (device_path) { _cleanup_freepool_ EFI_DEVICE_PATH *paths = NULL; - EFI_DEVICE_PATH *path; paths = UnpackDevicePath(device_path); - for (path = paths; !IsDevicePathEnd(path); path = NextDevicePathNode(path)) { + for (EFI_DEVICE_PATH *path = paths; !IsDevicePathEnd(path); path = NextDevicePathNode(path)) { HARDDRIVE_DEVICE_PATH *drive; if (DevicePathType(path) != MEDIA_DEVICE_PATH) diff --git a/src/boot/efi/pe.c b/src/boot/efi/pe.c index f99ecd0eda0..cb358380721 100644 --- a/src/boot/efi/pe.c +++ b/src/boot/efi/pe.c @@ -62,7 +62,6 @@ struct PeSectionHeader { EFI_STATUS pe_memory_locate_sections(CHAR8 *base, CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes) { struct DosFileHeader *dos; struct PeHeader *pe; - UINTN i; UINTN offset; dos = (struct DosFileHeader *)base; @@ -85,12 +84,11 @@ EFI_STATUS pe_memory_locate_sections(CHAR8 *base, CHAR8 **sections, UINTN *addrs offset = dos->ExeHeader + sizeof(*pe) + pe->FileHeader.SizeOfOptionalHeader; - for (i = 0; i < pe->FileHeader.NumberOfSections; i++) { + for (UINTN i = 0; i < pe->FileHeader.NumberOfSections; i++) { struct PeSectionHeader *sect; - UINTN j; sect = (struct PeSectionHeader *)&base[offset]; - for (j = 0; sections[j]; j++) { + for (UINTN j = 0; sections[j]; j++) { if (CompareMem(sect->Name, sections[j], strlena(sections[j])) != 0) continue; diff --git a/src/boot/efi/random-seed.c b/src/boot/efi/random-seed.c index b295b0b6bb1..cd402526078 100644 --- a/src/boot/efi/random-seed.c +++ b/src/boot/efi/random-seed.c @@ -86,7 +86,6 @@ static EFI_STATUS hash_many( VOID **ret) { _cleanup_freepool_ VOID *output = NULL; - UINTN i; /* Hashes the specified parameters in counter mode, generating n hash values, with the counter in the * range counter_start…counter_start+n-1. */ @@ -95,7 +94,7 @@ static EFI_STATUS hash_many( if (!output) return log_oom(); - for (i = 0; i < n; i++) + for (UINTN i = 0; i < n; i++) hash_once(old_seed, rng, size, system_token, system_token_size, counter_start + i, @@ -201,9 +200,7 @@ static VOID validate_sha256(void) { 0xaf, 0xac, 0x45, 0x03, 0x7a, 0xfe, 0xe9, 0xd1 }}, }; - UINTN i; - - for (i = 0; i < ELEMENTSOF(array); i++) { + for (UINTN i = 0; i < ELEMENTSOF(array); i++) { struct sha256_ctx hash; uint8_t result[HASH_VALUE_SIZE]; diff --git a/src/boot/efi/sha256.c b/src/boot/efi/sha256.c index f23066d0acf..774f0eeb6c0 100644 --- a/src/boot/efi/sha256.c +++ b/src/boot/efi/sha256.c @@ -94,7 +94,7 @@ void sha256_init_ctx(struct sha256_ctx *ctx) { void *sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf) { /* Take yet unprocessed bytes into account. */ UINT32 bytes = ctx->buflen; - UINTN pad, i; + UINTN pad; /* Now count remaining bytes. */ ctx->total64 += bytes; @@ -111,7 +111,7 @@ void *sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf) { sha256_process_block (ctx->buffer, bytes + pad + 8, ctx); /* Put result from CTX in first 32 bytes following RESBUF. */ - for (i = 0; i < 8; ++i) + for (UINTN i = 0; i < 8; ++i) ((UINT32 *) resbuf)[i] = SWAP (ctx->H[i]); return resbuf; @@ -214,7 +214,6 @@ static void sha256_process_block(const void *buffer, UINTN len, struct sha256_ct UINT32 f_save = f; UINT32 g_save = g; UINT32 h_save = h; - UINTN t; /* Operators defined in FIPS 180-2:4.1.2. */ #define Ch(x, y, z) ((x & y) ^ (~x & z)) @@ -229,15 +228,15 @@ static void sha256_process_block(const void *buffer, UINTN len, struct sha256_ct #define CYCLIC(w, s) ((w >> s) | (w << (32 - s))) /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */ - for (t = 0; t < 16; ++t) { + for (UINTN t = 0; t < 16; ++t) { W[t] = SWAP (*words); ++words; } - for (t = 16; t < 64; ++t) + for (UINTN t = 16; t < 64; ++t) W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16]; /* The actual computation according to FIPS 180-2:6.2.2 step 3. */ - for (t = 0; t < 64; ++t) { + for (UINTN t = 0; t < 64; ++t) { UINT32 T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t]; UINT32 T2 = S0 (a) + Maj (a, b, c); h = g; diff --git a/src/boot/efi/splash.c b/src/boot/efi/splash.c index 552c45cff49..5e085ec45c2 100644 --- a/src/boot/efi/splash.c +++ b/src/boot/efi/splash.c @@ -151,22 +151,18 @@ static EFI_STATUS bmp_to_blt(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *buf, struct bmp_dib *dib, struct bmp_map *map, UINT8 *pixmap) { UINT8 *in; - UINTN y; /* transform and copy pixels */ in = pixmap; - for (y = 0; y < dib->y; y++) { + for (UINTN y = 0; y < dib->y; y++) { EFI_GRAPHICS_OUTPUT_BLT_PIXEL *out; UINTN row_size; - UINTN x; out = &buf[(dib->y - y - 1) * dib->x]; - for (x = 0; x < dib->x; x++, in++, out++) { + for (UINTN x = 0; x < dib->x; x++, in++, out++) { switch (dib->depth) { case 1: { - UINTN i; - - for (i = 0; i < 8 && x < dib->x; i++) { + for (UINTN i = 0; i < 8 && x < dib->x; i++) { out->Red = map[((*in) >> (7 - i)) & 1].red; out->Green = map[((*in) >> (7 - i)) & 1].green; out->Blue = map[((*in) >> (7 - i)) & 1].blue; diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index 2dffa4138ad..92999166d0b 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -59,12 +59,11 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { *(CHAR16 *) loaded_image->LoadOptions > 0x1F) { CHAR16 *options; CHAR8 *line; - UINTN i; options = (CHAR16 *)loaded_image->LoadOptions; cmdline_len = (loaded_image->LoadOptionsSize / sizeof(CHAR16)) * sizeof(CHAR8); line = AllocatePool(cmdline_len); - for (i = 0; i < cmdline_len; i++) + for (UINTN i = 0; i < cmdline_len; i++) line[i] = options[i]; cmdline = line; diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index 9019cd7a252..0d057d809d7 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -193,7 +193,6 @@ VOID efivar_set_time_usec(const EFI_GUID *vendor, CHAR16 *name, UINT64 usec) { static INTN utf8_to_16(CHAR8 *stra, CHAR16 *c) { CHAR16 unichar; UINTN len; - UINTN i; if (!(stra[0] & 0x80)) len = 1; @@ -231,7 +230,7 @@ static INTN utf8_to_16(CHAR8 *stra, CHAR16 *c) { break; } - for (i = 1; i < len; i++) { + for (UINTN i = 1; i < len; i++) { if ((stra[i] & 0xc0) != 0x80) return -1; unichar <<= 6; From a7308a266b38a9cf3eae7e9c0b86ec27e0707f45 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 1 Feb 2021 22:32:26 +0000 Subject: [PATCH 07/12] boot: Rename efivar_get/set_int() to efivar_get/set_uint_string() Let's clearly indicate that these are used to set/get uints that are stored as strings. --- src/boot/efi/boot.c | 10 +++++----- src/boot/efi/util.c | 4 ++-- src/boot/efi/util.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index da3bd119754..9cdcd29677b 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -421,7 +421,7 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { Print(L"entry EFI var idx: %d\n", config->idx_default_efivar); Print(L"\n"); - if (efivar_get_int(LOADER_GUID, L"LoaderConfigTimeout", &timeout) == EFI_SUCCESS) + if (efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeout", &timeout) == EFI_SUCCESS) Print(L"LoaderConfigTimeout: %u\n", timeout); if (config->entry_oneshot) @@ -781,7 +781,7 @@ static BOOLEAN menu_run( case KEYPRESS(0, 0, 'T'): if (config->timeout_sec_efivar > 0) { config->timeout_sec_efivar--; - efivar_set_int( + efivar_set_uint_string( LOADER_GUID, L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE); if (config->timeout_sec_efivar > 0) status = PoolPrint(L"Menu timeout set to %d sec.", config->timeout_sec_efivar); @@ -803,7 +803,7 @@ static BOOLEAN menu_run( if (config->timeout_sec_efivar == -1 && config->timeout_sec_config == 0) config->timeout_sec_efivar++; config->timeout_sec_efivar++; - efivar_set_int(LOADER_GUID, L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE); + efivar_set_uint_string(LOADER_GUID, L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE); if (config->timeout_sec_efivar > 0) status = PoolPrint(L"Menu timeout set to %d sec.", config->timeout_sec_efivar); @@ -1460,14 +1460,14 @@ static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) { if (!EFI_ERROR(err)) config_defaults_load_from_file(config, content); - err = efivar_get_int(LOADER_GUID, L"LoaderConfigTimeout", &sec); + err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeout", &sec); if (!EFI_ERROR(err)) { config->timeout_sec_efivar = sec > INTN_MAX ? INTN_MAX : sec; config->timeout_sec = sec; } else config->timeout_sec_efivar = -1; - err = efivar_get_int(LOADER_GUID, L"LoaderConfigTimeoutOneShot", &sec); + err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeoutOneShot", &sec); if (!EFI_ERROR(err)) { /* Unset variable now, after all it's "one shot". */ (void) efivar_set(LOADER_GUID, L"LoaderConfigTimeoutOneShot", NULL, TRUE); diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index 0d057d809d7..dea4872158c 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -90,7 +90,7 @@ EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 * vendor, name, value, value ? (StrLen(value) + 1) * sizeof(CHAR16) : 0, persistent); } -EFI_STATUS efivar_set_int(const EFI_GUID *vendor, CHAR16 *name, UINTN i, BOOLEAN persistent) { +EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, CHAR16 *name, UINTN i, BOOLEAN persistent) { CHAR16 str[32]; SPrint(str, 32, L"%u", i); @@ -132,7 +132,7 @@ EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value return EFI_SUCCESS; } -EFI_STATUS efivar_get_int(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i) { +EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i) { _cleanup_freepool_ CHAR16 *val = NULL; EFI_STATUS err; diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index 07882383d4d..f0e96106297 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -23,12 +23,12 @@ UINT64 time_usec(void); EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent); EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const VOID *buf, UINTN size, BOOLEAN persistent); -EFI_STATUS efivar_set_int(const EFI_GUID *vendor, CHAR16 *name, UINTN i, BOOLEAN persistent); +EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, CHAR16 *name, UINTN i, BOOLEAN persistent); VOID efivar_set_time_usec(const EFI_GUID *vendor, CHAR16 *name, UINT64 usec); EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value); EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size); -EFI_STATUS efivar_get_int(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i); +EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i); EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOOLEAN *ret); CHAR8 *strchra(CHAR8 *s, CHAR8 c); From 987d0a12507d7ba41803c26de679be902ba43a05 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 1 Feb 2021 21:56:30 +0000 Subject: [PATCH 08/12] boot: Add efivar_get/set_uint64_le() functions These are implemented as bit-shifting functions that allow reading and writing UEFI variables stored as little endian 64-bit unsigned values. --- src/boot/efi/util.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ src/boot/efi/util.h | 4 +++ 2 files changed, 65 insertions(+) diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index dea4872158c..50ad7575655 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -97,6 +97,32 @@ EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, CHAR16 *name, UINTN i, return efivar_set(vendor, name, str, persistent); } +EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, CHAR16 *name, UINT32 value, BOOLEAN persistent) { + UINT8 buf[4]; + + buf[0] = (UINT8)(value >> 0U & 0xFF); + buf[1] = (UINT8)(value >> 8U & 0xFF); + buf[2] = (UINT8)(value >> 16U & 0xFF); + buf[3] = (UINT8)(value >> 24U & 0xFF); + + return efivar_set_raw(vendor, name, buf, sizeof(buf), persistent); +} + +EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, CHAR16 *name, UINT64 value, BOOLEAN persistent) { + UINT8 buf[8]; + + buf[0] = (UINT8)(value >> 0U & 0xFF); + buf[1] = (UINT8)(value >> 8U & 0xFF); + buf[2] = (UINT8)(value >> 16U & 0xFF); + buf[3] = (UINT8)(value >> 24U & 0xFF); + buf[4] = (UINT8)(value >> 32U & 0xFF); + buf[5] = (UINT8)(value >> 40U & 0xFF); + buf[6] = (UINT8)(value >> 48U & 0xFF); + buf[7] = (UINT8)(value >> 56U & 0xFF); + + return efivar_set_raw(vendor, name, buf, sizeof(buf), persistent); +} + EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value) { _cleanup_freepool_ CHAR8 *buf = NULL; EFI_STATUS err; @@ -143,6 +169,41 @@ EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UI return err; } +EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT32 *ret) { + _cleanup_freepool_ CHAR8 *buf = NULL; + UINTN size; + EFI_STATUS err; + + err = efivar_get_raw(vendor, name, &buf, &size); + if (!EFI_ERROR(err) && ret) { + if (size != sizeof(UINT32)) + return EFI_BUFFER_TOO_SMALL; + + *ret = (UINT32) buf[0] << 0U | (UINT32) buf[1] << 8U | (UINT32) buf[2] << 16U | + (UINT32) buf[3] << 24U; + } + + return err; +} + +EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 *ret) { + _cleanup_freepool_ CHAR8 *buf = NULL; + UINTN size; + EFI_STATUS err; + + err = efivar_get_raw(vendor, name, &buf, &size); + if (!EFI_ERROR(err) && ret) { + if (size != sizeof(UINT64)) + return EFI_BUFFER_TOO_SMALL; + + *ret = (UINT64) buf[0] << 0U | (UINT64) buf[1] << 8U | (UINT64) buf[2] << 16U | + (UINT64) buf[3] << 24U | (UINT64) buf[4] << 32U | (UINT64) buf[5] << 40U | + (UINT64) buf[6] << 48U | (UINT64) buf[7] << 56U; + } + + return err; +} + EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size) { _cleanup_freepool_ CHAR8 *buf = NULL; UINTN l; diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index f0e96106297..313d6697d2e 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -24,11 +24,15 @@ UINT64 time_usec(void); EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent); EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const VOID *buf, UINTN size, BOOLEAN persistent); EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, CHAR16 *name, UINTN i, BOOLEAN persistent); +EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, CHAR16 *NAME, UINT32 value, BOOLEAN persistent); +EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, CHAR16 *name, UINT64 value, BOOLEAN persistent); VOID efivar_set_time_usec(const EFI_GUID *vendor, CHAR16 *name, UINT64 usec); EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value); EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size); EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i); +EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT32 *ret); +EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 *ret); EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOOLEAN *ret); CHAR8 *strchra(CHAR8 *s, CHAR8 c); From c8af7dab217801740d784ee3c14059f3653a78a6 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 1 Feb 2021 21:57:58 +0000 Subject: [PATCH 09/12] boot: Replace raw efivar gets with typed variants --- src/boot/efi/boot.c | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 9cdcd29677b..fcd1b099c5a 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -356,11 +356,11 @@ static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) { } static VOID print_status(Config *config, CHAR16 *loaded_image_path) { - UINT64 key; + UINT64 key, indvar; UINTN timeout; - _cleanup_freepool_ CHAR8 *modevar = NULL, *indvar = NULL; + BOOLEAN modevar; _cleanup_freepool_ CHAR16 *partstr = NULL, *defaultstr = NULL; - UINTN x, y, size; + UINTN x, y; uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTGRAY|EFI_BACKGROUND_BLACK); uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); @@ -377,14 +377,14 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) { Print(L"SecureBoot: %s\n", yes_no(secure_boot_enabled())); - if (efivar_get_raw(EFI_GLOBAL_GUID, L"SetupMode", &modevar, &size) == EFI_SUCCESS) - Print(L"SetupMode: %s\n", *modevar > 0 ? L"setup" : L"user"); + if (efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SetupMode", &modevar) == EFI_SUCCESS) + Print(L"SetupMode: %s\n", modevar ? L"setup" : L"user"); if (shim_loaded()) Print(L"Shim: present\n"); - if (efivar_get_raw(EFI_GLOBAL_GUID, L"OsIndicationsSupported", &indvar, &size) == EFI_SUCCESS) - Print(L"OsIndicationsSupported: %d\n", (UINT64)*indvar); + if (efivar_get_uint64_le(EFI_GLOBAL_GUID, L"OsIndicationsSupported", &indvar) == EFI_SUCCESS) + Print(L"OsIndicationsSupported: %d\n", indvar); Print(L"\n--- press key ---\n\n"); console_key_read(&key, TRUE); @@ -2276,18 +2276,16 @@ out_unload: } static EFI_STATUS reboot_into_firmware(VOID) { - _cleanup_freepool_ CHAR8 *b = NULL; - UINTN size; - UINT64 osind; + UINT64 old, new; EFI_STATUS err; - osind = EFI_OS_INDICATIONS_BOOT_TO_FW_UI; + new = EFI_OS_INDICATIONS_BOOT_TO_FW_UI; - err = efivar_get_raw(EFI_GLOBAL_GUID, L"OsIndications", &b, &size); + err = efivar_get_uint64_le(EFI_GLOBAL_GUID, L"OsIndications", &old); if (!EFI_ERROR(err)) - osind |= (UINT64)*b; + new |= old; - err = efivar_set_raw(EFI_GLOBAL_GUID, L"OsIndications", &osind, sizeof(UINT64), TRUE); + err = efivar_set_uint64_le(EFI_GLOBAL_GUID, L"OsIndications", new, TRUE); if (EFI_ERROR(err)) return err; @@ -2341,8 +2339,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { 0; _cleanup_freepool_ CHAR16 *infostr = NULL, *typestr = NULL; - CHAR8 *b; - UINTN size; + UINT64 osind = 0; EFI_LOADED_IMAGE *loaded_image; EFI_FILE *root_dir; CHAR16 *loaded_image_path; @@ -2363,7 +2360,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { typestr = PoolPrint(L"UEFI %d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); efivar_set(LOADER_GUID, L"LoaderFirmwareType", typestr, FALSE); - (void) efivar_set_raw(LOADER_GUID, L"LoaderFeatures", &loader_features, sizeof(loader_features), FALSE); + (void) efivar_set_uint64_le(LOADER_GUID, L"LoaderFeatures", loader_features, FALSE); err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image, image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); @@ -2420,15 +2417,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { L"auto-efi-default", '\0', L"EFI Default Loader", L"\\EFI\\Boot\\boot" EFI_MACHINE_TYPE_NAME ".efi"); config_entry_add_osx(&config); - if (config.auto_firmware && efivar_get_raw(EFI_GLOBAL_GUID, L"OsIndicationsSupported", &b, &size) == EFI_SUCCESS) { - UINT64 osind = (UINT64)*b; - + if (config.auto_firmware && efivar_get_uint64_le(EFI_GLOBAL_GUID, L"OsIndicationsSupported", &osind) == EFI_SUCCESS) { if (osind & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) config_entry_add_call(&config, L"auto-reboot-to-firmware-setup", L"Reboot Into Firmware Interface", reboot_into_firmware); - FreePool(b); } if (config.entry_count == 0) { From d47b7c5720bddbaa54687b14fff1c9a81773538e Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Sun, 31 Jan 2021 21:49:17 +0000 Subject: [PATCH 10/12] boot: Fix void pointer arithmetic warning --- src/boot/efi/stub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index 92999166d0b..0bef6b1c44f 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -50,7 +50,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { } if (szs[0] > 0) - cmdline = (CHAR8 *)(loaded_image->ImageBase + addrs[0]); + cmdline = (CHAR8 *)(loaded_image->ImageBase) + addrs[0]; cmdline_len = szs[0]; From fffd5e8ee312c7ef55058b61b2b619c7e3c48925 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 1 Feb 2021 22:02:08 +0000 Subject: [PATCH 11/12] boot: Drop unnecessary braces --- src/boot/efi/boot.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index fcd1b099c5a..8b5bcd3683b 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -1820,11 +1820,10 @@ static BOOLEAN config_entry_add_loader_auto( /* look for systemd-boot magic string */ err = file_read(root_dir, loader, 0, 100*1024, &content, &len); - if (!EFI_ERROR(err)) { + if (!EFI_ERROR(err)) for (CHAR8 *start = content; start <= content + len - sizeof(magic) - 1; start++) if (start[0] == magic[0] && CompareMem(start, magic, sizeof(magic) - 1) == 0) return FALSE; - } } /* check existence */ From cb347d263d38ee3d9fb9be588a6efd77bca218ea Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 2 Feb 2021 22:27:09 +0000 Subject: [PATCH 12/12] boot: Add startswith() and endswith() functions with no_case variants Adapted from string-util --- src/boot/efi/boot.c | 16 ++++--------- src/boot/efi/util.c | 56 +++++++++++++++++++++++++++++++++++++++++++++ src/boot/efi/util.h | 6 +++++ 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 8b5bcd3683b..c88a6db9dee 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -1493,7 +1493,6 @@ static VOID config_load_entries( UINTN bufsize; EFI_FILE_INFO *f; _cleanup_freepool_ CHAR8 *content = NULL; - UINTN len; bufsize = sizeof(buf); err = uefi_call_wrapper(entries_dir->Read, 3, entries_dir, &bufsize, buf); @@ -1506,12 +1505,9 @@ static VOID config_load_entries( if (f->Attribute & EFI_FILE_DIRECTORY) continue; - len = StrLen(f->FileName); - if (len < 6) + if (!endswith_no_case(f->FileName, L".conf")) continue; - if (StriCmp(f->FileName + len - 5, L".conf") != 0) - continue; - if (StrnCmp(f->FileName, L"auto-", 5) == 0) + if (startswith(f->FileName, L"auto-")) continue; err = file_read(entries_dir, f->FileName, 0, 0, &content, NULL); @@ -1894,7 +1890,6 @@ static VOID config_entry_add_linux( UINTN szs[ELEMENTSOF(sections)-1] = {}; UINTN addrs[ELEMENTSOF(sections)-1] = {}; CHAR8 *content = NULL; - UINTN len; CHAR8 *line; UINTN pos = 0; CHAR8 *key, *value; @@ -1914,12 +1909,9 @@ static VOID config_entry_add_linux( continue; if (f->Attribute & EFI_FILE_DIRECTORY) continue; - len = StrLen(f->FileName); - if (len < 5) + if (!endswith_no_case(f->FileName, L".efi")) continue; - if (StriCmp(f->FileName + len - 4, L".efi") != 0) - continue; - if (StrnCmp(f->FileName, L"auto-", 5) == 0) + if (startswith(f->FileName, L"auto-")) continue; /* look for .osrel and .cmdline sections in the .efi binary */ diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index 50ad7575655..8adf3f5fe45 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -375,6 +375,62 @@ CHAR8 *strchra(CHAR8 *s, CHAR8 c) { return NULL; } +const CHAR16 *startswith(const CHAR16 *s, const CHAR16 *prefix) { + UINTN l; + + l = StrLen(prefix); + if (StrnCmp(s, prefix, l) == 0) + return s + l; + + return NULL; +} + +const CHAR16 *endswith(const CHAR16 *s, const CHAR16 *postfix) { + UINTN sl, pl; + + sl = StrLen(s); + pl = StrLen(postfix); + + if (pl == 0) + return s + sl; + + if (sl < pl) + return NULL; + + if (StrnCmp(s + sl - pl, postfix, pl) != 0) + return NULL; + + return s + sl - pl; +} + +const CHAR16 *startswith_no_case(const CHAR16 *s, const CHAR16 *prefix) { + UINTN l; + + l = StrLen(prefix); + if (StriCmp(s, prefix) == 0) + return s + l; + + return NULL; +} + +const CHAR16 *endswith_no_case(const CHAR16 *s, const CHAR16 *postfix) { + UINTN sl, pl; + + sl = StrLen(s); + pl = StrLen(postfix); + + if (pl == 0) + return s + sl; + + if (sl < pl) + return NULL; + + if (StriCmp(s + sl - pl, postfix) != 0) + return NULL; + + return s + sl - pl; +} + EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **ret, UINTN *ret_size) { _cleanup_(FileHandleClosep) EFI_FILE_HANDLE handle = NULL; _cleanup_freepool_ CHAR8 *buf = NULL; diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index 313d6697d2e..f2be857d427 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -39,6 +39,12 @@ CHAR8 *strchra(CHAR8 *s, CHAR8 c); CHAR16 *stra_to_path(CHAR8 *stra); CHAR16 *stra_to_str(CHAR8 *stra); +const CHAR16 *startswith(const CHAR16 *s, const CHAR16 *prefix); +const CHAR16 *endswith(const CHAR16 *s, const CHAR16 *postfix); + +const CHAR16 *startswith_no_case(const CHAR16 *s, const CHAR16 *prefix); +const CHAR16 *endswith_no_case(const CHAR16 *s, const CHAR16 *postfix); + EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **content, UINTN *content_size); static inline void FreePoolp(void *p) {