diff options
| author | Peter Jones <pjones@redhat.com> | 2015-06-11 13:25:56 -0400 |
|---|---|---|
| committer | Peter Jones <pjones@redhat.com> | 2015-06-11 13:25:56 -0400 |
| commit | 0a7003faec146ff1db829cc2d896ab093da7def0 (patch) | |
| tree | 38a86f63b8457ecb46f2d68f6218735557f430ea /replacements.c | |
| parent | b9f98904ba133f437ced3660b3b9f033f02244ec (diff) | |
| download | efi-boot-shim-0a7003faec146ff1db829cc2d896ab093da7def0.tar.gz efi-boot-shim-0a7003faec146ff1db829cc2d896ab093da7def0.zip | |
Ensure that apps launched by shim get correct BS->Exit() behavior
Right now applications run by shim get our wrapper for Exit(), but it
doesn't do as much cleanup as it should - shim itself also exits, but
currently is not doing all the cleanup it should be doing.
This changes it so all of shim's cleanup is also performed.
Based on a patch and lots of review from Gary Lin.
Signed-off-by: Peter Jones <pjones@redhat.com>
Diffstat (limited to 'replacements.c')
| -rw-r--r-- | replacements.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/replacements.c b/replacements.c index f7623d9d..01eda0e3 100644 --- a/replacements.c +++ b/replacements.c @@ -73,7 +73,6 @@ unhook_system_services(void) if (!systab) return; - systab->BootServices->Exit = system_exit; systab->BootServices->LoadImage = system_load_image; systab->BootServices->StartImage = system_start_image; systab->BootServices->ExitBootServices = system_exit_boot_services; @@ -163,18 +162,30 @@ exit_boot_services(EFI_HANDLE image_key, UINTN map_key) static EFI_STATUS EFIAPI do_exit(EFI_HANDLE ImageHandle, EFI_STATUS ExitStatus, - UINTN ExitDataSize, CHAR16 *ExitData) + UINTN ExitDataSize, CHAR16 *ExitData) { EFI_STATUS status; - unhook_system_services(); - status = systab->BootServices->Exit(ImageHandle, ExitStatus, ExitDataSize, ExitData); - if (EFI_ERROR(status)) - hook_system_services(systab); + shim_fini(); + + status = systab->BootServices->Exit(ImageHandle, ExitStatus, + ExitDataSize, ExitData); + if (EFI_ERROR(status)) { + EFI_STATUS status2 = shim_init(); + + if (EFI_ERROR(status2)) { + Print(L"Something has gone seriously wrong: %r\n", + status2); + Print(L"shim cannot continue, sorry.\n"); + systab->BootServices->Stall(5000000); + systab->RuntimeServices->ResetSystem( + EfiResetShutdown, + EFI_SECURITY_VIOLATION, 0, NULL); + } + } return status; } - void hook_system_services(EFI_SYSTEM_TABLE *local_systab) { @@ -201,6 +212,18 @@ hook_system_services(EFI_SYSTEM_TABLE *local_systab) * and b) we can unwrap when we're done. */ system_exit_boot_services = systab->BootServices->ExitBootServices; systab->BootServices->ExitBootServices = exit_boot_services; +} + +void +unhook_exit(void) +{ + systab->BootServices->Exit = system_exit; +} + +void +hook_exit(EFI_SYSTEM_TABLE *local_systab) +{ + systab = local_systab; /* we need to hook Exit() so that we can allow users to quit the * bootloader and still e.g. start a new one or run an internal |
