diff options
| author | Gary Lin <glin@suse.com> | 2018-05-23 18:13:05 +0800 |
|---|---|---|
| committer | Javier Martinez Canillas <javier@dowhile0.org> | 2021-02-16 09:12:48 +0100 |
| commit | a5db51a52e8d4cae938fc807b991383309dffca7 (patch) | |
| tree | d07ee85bf52243bda9e3cd1bc4dd43dc84616bf3 | |
| parent | 4e111bf1afaff2e89e51574c61631cd4375d4fdd (diff) | |
| download | efi-boot-shim-a5db51a52e8d4cae938fc807b991383309dffca7.tar.gz efi-boot-shim-a5db51a52e8d4cae938fc807b991383309dffca7.zip | |
fallback: show a countdown menu before reset
Some machines with the faulty firmware may keep booting the default boot
path instead of the boot option we create. To avoid the infinite reset
loop, this commit introduce a countdown screen before fallback resets the
system, so the user can interrupt the system reset and choose to boot
the restored boot option. The "Always continue boot" option creates a
BS+RT+NV variable, FB_NO_REBOOT, to make fallback boot the first boot
option afterward without asking. The user can revert the behavior by
removing the variable.
https://github.com/rhboot/shim/issues/128
Signed-off-by: Gary Lin <glin@suse.com>
This is a backport from devel of:
commit da6284569c4b5d60d14e6187f696f54cccb7b3d2
Author: Gary Lin <glin@suse.com>
Date: Wed May 23 18:13:05 2018 +0800
fallback: show a countdown menu before reset
Some machines with the faulty firmware may keep booting the default boot
path instead of the boot option we create. To avoid the infinite reset
loop, this commit introduce a countdown screen before fallback resets the
system, so the user can interrupt the system reset and choose to boot
the restored boot option. The "Always continue boot" option creates a
BS+RT+NV variable, FB_NO_REBOOT, to make fallback boot the first boot
option afterward without asking. The user can revert the behavior by
removing the variable.
https://github.com/rhboot/shim/issues/128
Signed-off-by: Gary Lin <glin@suse.com>
Signed-off-by: Peter Jones <pjones@redhat.com>
| -rw-r--r-- | fallback.c | 81 |
1 files changed, 81 insertions, 0 deletions
@@ -9,6 +9,8 @@ #include "shim.h" +#define NO_REBOOT L"FB_NO_REBOOT" + EFI_LOADED_IMAGE *this_image = NULL; int @@ -971,6 +973,65 @@ try_start_first_option(EFI_HANDLE parent_image_handle) return efi_status; } +static UINT32 +get_fallback_no_reboot(void) +{ + EFI_STATUS efi_status; + UINT32 no_reboot; + UINTN size = sizeof(UINT32); + + efi_status = gRT->GetVariable(NO_REBOOT, &SHIM_LOCK_GUID, + NULL, &size, &no_reboot); + if (!EFI_ERROR(efi_status)) { + return no_reboot; + } + return 0; +} + +static EFI_STATUS +set_fallback_no_reboot(void) +{ + EFI_STATUS efi_status; + UINT32 no_reboot = 1; + efi_status = gRT->SetVariable(NO_REBOOT, &SHIM_LOCK_GUID, + EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS + | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(UINT32), &no_reboot); + return efi_status; +} + +static int +draw_countdown(void) +{ + CHAR16 *title = L"Boot Option Restoration"; + CHAR16 *message = L"Press any key to stop system reset"; + int timeout; + + timeout = console_countdown(title, message, 5); + + return timeout; +} + +static int +get_user_choice(void) +{ + int choice; + CHAR16 *title[] = {L"Boot Option Restored", NULL}; + CHAR16 *menu_strings[] = { + L"Reset system", + L"Continue boot", + L"Always continue boot", + NULL + }; + + do { + choice = console_select(title, menu_strings, 0); + } while (choice < 0 || choice > 2); + + return choice; +} + extern EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab); @@ -1037,6 +1098,26 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) VerbosePrint(L"tpm not present, starting the first image\n"); try_start_first_option(image); } else { + if (get_fallback_no_reboot() == 1) { + VerbosePrint(L"NO_REBOOT is set, starting the first image\n"); + try_start_first_option(image); + } + + int timeout = draw_countdown(); + if (timeout == 0) + goto reset; + + int choice = get_user_choice(); + if (choice == 0) { + goto reset; + } else if (choice == 2) { + efi_status = set_fallback_no_reboot(); + if (EFI_ERROR(efi_status)) + goto reset; + } + VerbosePrint(L"tpm present, starting the first image\n"); + try_start_first_option(image); +reset: VerbosePrint(L"tpm present, resetting system\n"); } |
