610f2a3193
- Add shim-update-cryptlib.patch to update Cryptlib to r16559 and openssl to 0.9.8zf - Add shim-bsc919675-uninstall-shim-protocols.patch to uninstall the shim protocols at Exit (bsc#919675) - Add shim-bsc920515-fix-fallback-buffer-length.patch to adjust the buffer size for the boot options (bsc#920515) - Refresh shim-opensuse-cert-prompt.patch OBS-URL: https://build.opensuse.org/request/show/294902 OBS-URL: https://build.opensuse.org/package/show/devel:openSUSE:Factory/shim?expand=0&rev=96
146 lines
4.7 KiB
Diff
146 lines
4.7 KiB
Diff
From 4f8bf8c570dadf8044e7f3f260c55e3e22630998 Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Tue, 3 Mar 2015 16:53:11 +0800
|
|
Subject: [PATCH] Uninstall shim protocols at Exit()
|
|
|
|
Shim uninstalls its own protocol at the end of the program. However,
|
|
if the loaded binary, e.g. grub2, calls Exit(), the uninstall function
|
|
would never be called, i.e. the shim protocol handle existed even if
|
|
shim was gone. This already caused crashes on the dell machines with
|
|
the following steps:
|
|
|
|
1. boot to grub2 and press 'C' for the grub2 shell
|
|
2. type "exit" to quit the shell
|
|
3. boot to grub2 again and boot an OS
|
|
|
|
While grub2 uses the shim protocol to verify the OS image, it may get
|
|
the old dead shim handle and crash the system.
|
|
|
|
This commit adds uninstall_shim_protocols() to the hooked exit function
|
|
and always hook Exit to clean up the protocol handle.
|
|
|
|
Signed-off-by: Gary Ching-Pang Lin <glin@suse.com>
|
|
---
|
|
replacements.c | 35 ++++++++++++++++++++++++++++-------
|
|
replacements.h | 1 +
|
|
shim.c | 5 ++++-
|
|
3 files changed, 33 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/replacements.c b/replacements.c
|
|
index f7623d9..4d96e57 100644
|
|
--- a/replacements.c
|
|
+++ b/replacements.c
|
|
@@ -74,6 +74,10 @@ unhook_system_services(void)
|
|
return;
|
|
|
|
systab->BootServices->Exit = system_exit;
|
|
+
|
|
+ if (hook_exit_only)
|
|
+ return;
|
|
+
|
|
systab->BootServices->LoadImage = system_load_image;
|
|
systab->BootServices->StartImage = system_start_image;
|
|
systab->BootServices->ExitBootServices = system_exit_boot_services;
|
|
@@ -167,10 +171,24 @@ do_exit(EFI_HANDLE ImageHandle, EFI_STATUS ExitStatus,
|
|
{
|
|
EFI_STATUS status;
|
|
unhook_system_services();
|
|
+ uninstall_shim_protocols();
|
|
|
|
status = systab->BootServices->Exit(ImageHandle, ExitStatus, ExitDataSize, ExitData);
|
|
- if (EFI_ERROR(status))
|
|
+ if (EFI_ERROR(status)) {
|
|
+ EFI_STATUS status2 = install_shim_protocols();
|
|
+
|
|
+ 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);
|
|
+ }
|
|
+
|
|
hook_system_services(systab);
|
|
+ }
|
|
return status;
|
|
}
|
|
|
|
@@ -182,6 +200,15 @@ hook_system_services(EFI_SYSTEM_TABLE *local_systab)
|
|
|
|
/* We need to hook various calls to make this work... */
|
|
|
|
+ /* 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
|
|
+ * shell. */
|
|
+ system_exit = systab->BootServices->Exit;
|
|
+ systab->BootServices->Exit = do_exit;
|
|
+
|
|
+ if (hook_exit_only)
|
|
+ return;
|
|
+
|
|
/* We need LoadImage() hooked so that fallback.c can load shim
|
|
* without having to fake LoadImage as well. This allows it
|
|
* to call the system LoadImage(), and have us track the output
|
|
@@ -201,10 +228,4 @@ 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;
|
|
-
|
|
- /* 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
|
|
- * shell. */
|
|
- system_exit = systab->BootServices->Exit;
|
|
- systab->BootServices->Exit = do_exit;
|
|
}
|
|
diff --git a/replacements.h b/replacements.h
|
|
index bd09424..928144d 100644
|
|
--- a/replacements.h
|
|
+++ b/replacements.h
|
|
@@ -37,6 +37,7 @@ typedef enum {
|
|
|
|
extern verification_method_t verification_method;
|
|
extern int loader_is_participating;
|
|
+extern int hook_exit_only;
|
|
|
|
extern void hook_system_services(EFI_SYSTEM_TABLE *local_systab);
|
|
extern void unhook_system_services(void);
|
|
diff --git a/shim.c b/shim.c
|
|
index d46494a..6fbe427 100644
|
|
--- a/shim.c
|
|
+++ b/shim.c
|
|
@@ -90,6 +90,7 @@ UINT8 *vendor_dbx;
|
|
*/
|
|
verification_method_t verification_method;
|
|
int loader_is_participating;
|
|
+int exit_only;
|
|
|
|
#define EFI_IMAGE_SECURITY_DATABASE_GUID { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f }}
|
|
|
|
@@ -2100,6 +2101,7 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
|
|
/*
|
|
* Tell the user that we're in insecure mode if necessary
|
|
*/
|
|
+ hook_exit_only = 1;
|
|
if (user_insecure_mode) {
|
|
Print(L"Booting in insecure mode\n");
|
|
uefi_call_wrapper(BS->Stall, 1, 2000000);
|
|
@@ -2110,11 +2112,12 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
|
|
* that anything it boots has performed some
|
|
* validation of the next image.
|
|
*/
|
|
- hook_system_services(systab);
|
|
+ hook_exit_only = 0;
|
|
loader_is_participating = 0;
|
|
}
|
|
}
|
|
|
|
+ hook_system_services(systab);
|
|
efi_status = install_shim_protocols();
|
|
if (EFI_ERROR(efi_status))
|
|
return efi_status;
|
|
--
|
|
2.1.4
|
|
|