sd-boot: Unify error handling
log_error_stall() and log_error_status_stall() will ensure the user has a chance to catch an error message by stalling and also forcing a lightred/black color on it. Also, convert several Print() calls to it since they are actually error messages.
This commit is contained in:
+19
-43
@@ -527,7 +527,7 @@ static BOOLEAN menu_run(
|
||||
err = console_set_mode(&config->console_mode, config->console_mode_change);
|
||||
if (EFI_ERROR(err)) {
|
||||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||
Print(L"Error switching console mode to %ld: %r.\r", (UINT64)config->console_mode, err);
|
||||
log_error_stall(L"Error switching console mode to %lu: %r", (UINT64)config->console_mode, err);
|
||||
}
|
||||
} else
|
||||
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||
@@ -1221,8 +1221,7 @@ static VOID config_entry_bump_counters(
|
||||
break;
|
||||
|
||||
if (r != EFI_BUFFER_TOO_SMALL || file_info_size * 2 < file_info_size) {
|
||||
Print(L"\nFailed to get file info for '%s': %r\n", old_path, r);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
log_error_stall(L"Failed to get file info for '%s': %r", old_path, r);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1234,8 +1233,7 @@ static VOID config_entry_bump_counters(
|
||||
StrCpy(file_info->FileName, entry->next_name);
|
||||
r = uefi_call_wrapper(handle->SetInfo, 4, handle, &EfiFileInfoGuid, file_info_size, file_info);
|
||||
if (EFI_ERROR(r)) {
|
||||
Print(L"\nFailed to rename '%s' to '%s', ignoring: %r\n", old_path, entry->next_name, r);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
log_error_stall(L"Failed to rename '%s' to '%s', ignoring: %r", old_path, entry->next_name, r);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2165,18 +2163,12 @@ static EFI_STATUS image_start(
|
||||
EFI_STATUS err;
|
||||
|
||||
path = FileDevicePath(entry->device, entry->loader);
|
||||
if (!path) {
|
||||
Print(L"Error getting device path.");
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
if (!path)
|
||||
return log_error_status_stall(EFI_INVALID_PARAMETER, L"Error getting device path.");
|
||||
|
||||
err = uefi_call_wrapper(BS->LoadImage, 6, FALSE, parent_image, path, NULL, 0, &image);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Error loading %s: %r", entry->loader, err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return err;
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Error loading %s: %r", entry->loader, err);
|
||||
|
||||
if (config->options_edit)
|
||||
options = config->options_edit;
|
||||
@@ -2190,8 +2182,7 @@ static EFI_STATUS image_start(
|
||||
err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
|
||||
parent_image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Error getting LoadedImageProtocol handle: %r", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
log_error_stall(L"Error getting LoadedImageProtocol handle: %r", err);
|
||||
goto out_unload;
|
||||
}
|
||||
loaded_image->LoadOptions = options;
|
||||
@@ -2202,10 +2193,8 @@ static EFI_STATUS image_start(
|
||||
err = tpm_log_event(SD_TPM_PCR,
|
||||
(EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->LoadOptions,
|
||||
loaded_image->LoadOptionsSize, loaded_image->LoadOptions);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Unable to add image options measurement: %r", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 200 * 1000);
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
log_error_stall(L"Unable to add image options measurement: %r", err);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2231,9 +2220,7 @@ static EFI_STATUS reboot_into_firmware(VOID) {
|
||||
return err;
|
||||
|
||||
err = uefi_call_wrapper(RT->ResetSystem, 4, EfiResetCold, EFI_SUCCESS, 0, NULL);
|
||||
Print(L"Error calling ResetSystem: %r", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return err;
|
||||
return log_error_status_stall(err, L"Error calling ResetSystem: %r", err);
|
||||
}
|
||||
|
||||
static VOID config_free(Config *config) {
|
||||
@@ -2305,30 +2292,21 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
|
||||
err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
|
||||
image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Error getting a LoadedImageProtocol handle: %r", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return err;
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err);
|
||||
|
||||
/* export the device path this image is started from */
|
||||
if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS)
|
||||
efivar_set(LOADER_GUID, L"LoaderDevicePartUUID", uuid, 0);
|
||||
|
||||
root_dir = LibOpenRoot(loaded_image->DeviceHandle);
|
||||
if (!root_dir) {
|
||||
Print(L"Unable to open root directory.");
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return EFI_LOAD_ERROR;
|
||||
}
|
||||
if (!root_dir)
|
||||
return log_error_status_stall(EFI_LOAD_ERROR, L"Unable to open root directory.", EFI_LOAD_ERROR);
|
||||
|
||||
if (secure_boot_enabled() && shim_loaded()) {
|
||||
err = security_policy_install();
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Error installing security policy: %r ", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return err;
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Error installing security policy: %r", err);
|
||||
}
|
||||
|
||||
/* the filesystem path to this image, to prevent adding ourselves to the menu */
|
||||
@@ -2367,8 +2345,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
}
|
||||
|
||||
if (config.entry_count == 0) {
|
||||
Print(L"No loader found. Configuration files in \\loader\\entries\\*.conf are needed.");
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
log_error_stall(L"No loader found. Configuration files in \\loader\\entries\\*.conf are needed.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -2440,8 +2417,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
err = image_start(image, &config, entry);
|
||||
if (EFI_ERROR(err)) {
|
||||
graphics_mode(FALSE);
|
||||
Print(L"\nFailed to execute %s (%s): %r\n", entry->title, entry->loader, err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
log_error_stall(L"Failed to execute %s (%s): %r", entry->title, entry->loader, err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
+25
-48
@@ -35,10 +35,8 @@ static EFI_STATUS acquire_rng(UINTN size, VOID **ret) {
|
||||
return log_oom();
|
||||
|
||||
err = uefi_call_wrapper(rng->GetRNG, 3, rng, NULL, size, data);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Failed to acquire RNG data: %r\n", err);
|
||||
return err;
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Failed to acquire RNG data: %r", err);
|
||||
|
||||
*ret = TAKE_PTR(data);
|
||||
return EFI_SUCCESS;
|
||||
@@ -149,14 +147,12 @@ static EFI_STATUS acquire_system_token(VOID **ret, UINTN *ret_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);
|
||||
log_error_stall(L"Failed to read LoaderSystemToken EFI variable: %r", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (size <= 0) {
|
||||
Print(L"System token too short, ignoring.");
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
if (size <= 0)
|
||||
return log_error_status_stall(EFI_NOT_FOUND, L"System token too short, ignoring.");
|
||||
|
||||
*ret = TAKE_PTR(data);
|
||||
*ret_size = size;
|
||||
@@ -209,8 +205,7 @@ static VOID validate_sha256(void) {
|
||||
sha256_finish_ctx(&hash, result);
|
||||
|
||||
if (CompareMem(result, array[i].hash, HASH_VALUE_SIZE) != 0) {
|
||||
Print(L"SHA256 failed validation.\n");
|
||||
uefi_call_wrapper(BS->Stall, 1, 120 * 1000 * 1000);
|
||||
log_error_stall(L"SHA256 failed validation.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -246,7 +241,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &handle, (CHAR16*) L"\\loader\\random-seed", EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0ULL);
|
||||
if (EFI_ERROR(err)) {
|
||||
if (err != EFI_NOT_FOUND && err != EFI_WRITE_PROTECTED)
|
||||
Print(L"Failed to open random seed file: %r\n", err);
|
||||
log_error_stall(L"Failed to open random seed file: %r", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -255,15 +250,11 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
return log_oom();
|
||||
|
||||
size = info->FileSize;
|
||||
if (size < RANDOM_MAX_SIZE_MIN) {
|
||||
Print(L"Random seed file is too short?\n");
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
if (size < RANDOM_MAX_SIZE_MIN)
|
||||
return log_error_status_stall(EFI_INVALID_PARAMETER, L"Random seed file is too short.");
|
||||
|
||||
if (size > RANDOM_MAX_SIZE_MAX) {
|
||||
Print(L"Random seed file is too large?\n");
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
if (size > RANDOM_MAX_SIZE_MAX)
|
||||
return log_error_status_stall(EFI_INVALID_PARAMETER, L"Random seed file is too large.");
|
||||
|
||||
seed = AllocatePool(size);
|
||||
if (!seed)
|
||||
@@ -271,20 +262,14 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
|
||||
rsize = size;
|
||||
err = uefi_call_wrapper(handle->Read, 3, handle, &rsize, seed);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Failed to read random seed file: %r\n", err);
|
||||
return err;
|
||||
}
|
||||
if (rsize != size) {
|
||||
Print(L"Short read on random seed file\n");
|
||||
return EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Failed to read random seed file: %r", err);
|
||||
if (rsize != size)
|
||||
return log_error_status_stall(EFI_PROTOCOL_ERROR, L"Short read on random seed file.");
|
||||
|
||||
err = uefi_call_wrapper(handle->SetPosition, 2, handle, 0);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Failed to seek to beginning of random seed file: %r\n", err);
|
||||
return err;
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Failed to seek to beginning of random seed file: %r", err);
|
||||
|
||||
/* Request some random data from the UEFI RNG. We don't need this to work safely, but it's a good
|
||||
* idea to use it because it helps us for cases where users mistakenly include a random seed in
|
||||
@@ -299,27 +284,19 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
/* Update the random seed on disk before we use it */
|
||||
wsize = size;
|
||||
err = uefi_call_wrapper(handle->Write, 3, handle, &wsize, new_seed);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Failed to write random seed file: %r\n", err);
|
||||
return err;
|
||||
}
|
||||
if (wsize != size) {
|
||||
Print(L"Short write on random seed file\n");
|
||||
return EFI_PROTOCOL_ERROR;
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Failed to write random seed file: %r", err);
|
||||
if (wsize != size)
|
||||
return log_error_status_stall(EFI_PROTOCOL_ERROR, L"Short write on random seed file.");
|
||||
|
||||
err = uefi_call_wrapper(handle->Flush, 1, handle);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Failed to flush random seed file: %r\n");
|
||||
return err;
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Failed to flush random seed file: %r", err);
|
||||
|
||||
/* We are good to go */
|
||||
err = efivar_set_raw(LOADER_GUID, L"LoaderRandomSeed", for_kernel, size, 0);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Failed to write random seed to EFI variable: %r\n", err);
|
||||
return err;
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Failed to write random seed to EFI variable: %r", err);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
+7
-17
@@ -36,18 +36,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
|
||||
err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
|
||||
image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Error getting a LoadedImageProtocol handle: %r ", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return err;
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err);
|
||||
|
||||
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);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return err;
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
return log_error_status_stall(err, L"Unable to locate embedded .linux section: %r", err);
|
||||
|
||||
if (szs[0] > 0)
|
||||
cmdline = (CHAR8 *)(loaded_image->ImageBase) + addrs[0];
|
||||
@@ -72,10 +66,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
err = tpm_log_event(SD_TPM_PCR,
|
||||
(EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->LoadOptions,
|
||||
loaded_image->LoadOptionsSize, loaded_image->LoadOptions);
|
||||
if (EFI_ERROR(err)) {
|
||||
Print(L"Unable to add image options measurement: %r", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 200 * 1000);
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
log_error_stall(L"Unable to add image options measurement: %r", err);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -126,7 +118,5 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
(UINTN)loaded_image->ImageBase + addrs[2], szs[2]);
|
||||
|
||||
graphics_mode(FALSE);
|
||||
Print(L"Execution of embedded linux image failed: %r\n", err);
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
return err;
|
||||
return log_error_status_stall(err, L"Execution of embedded linux image failed: %r", err);
|
||||
}
|
||||
|
||||
+15
-2
@@ -425,8 +425,21 @@ EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN s
|
||||
return err;
|
||||
}
|
||||
|
||||
VOID log_error_stall(const CHAR16 *fmt, ...) {
|
||||
va_list args;
|
||||
|
||||
uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTRED|EFI_BACKGROUND_BLACK);
|
||||
|
||||
Print(L"\n");
|
||||
va_start(args, fmt);
|
||||
VPrint(fmt, args);
|
||||
va_end(args);
|
||||
Print(L"\n");
|
||||
|
||||
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
}
|
||||
|
||||
EFI_STATUS log_oom(void) {
|
||||
Print(L"Out of memory.");
|
||||
(void) uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
log_error_stall(L"Out of memory.");
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
@@ -74,4 +74,13 @@ static inline void FileHandleClosep(EFI_FILE_HANDLE *handle) {
|
||||
#define UINT64_MAX ((UINT64) -1)
|
||||
#endif
|
||||
|
||||
VOID log_error_stall(const CHAR16 *fmt, ...);
|
||||
EFI_STATUS log_oom(void);
|
||||
|
||||
/* This works just like log_error_errno() from userspace, but requires you
|
||||
* to provide err a second time if you want to use %r in the message! */
|
||||
#define log_error_status_stall(err, fmt, ...) \
|
||||
({ \
|
||||
log_error_stall(fmt, ##__VA_ARGS__); \
|
||||
err; \
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user