summaryrefslogtreecommitdiff
path: root/replacements.c
diff options
context:
space:
mode:
Diffstat (limited to 'replacements.c')
-rw-r--r--replacements.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/replacements.c b/replacements.c
index bf781a8b..469e73aa 100644
--- a/replacements.c
+++ b/replacements.c
@@ -78,8 +78,27 @@ replacement_start_image(EFI_HANDLE image_handle, UINTN *exit_data_size, CHAR16 *
unhook_system_services();
if (image_handle == last_loaded_image) {
+ UINT8 retain_protocol = 0;
+ UINTN retain_protocol_size = sizeof(retain_protocol);
+ UINT32 retain_protocol_attrs = 0;
+
loader_is_participating = 1;
- uninstall_shim_protocols();
+
+ /* If a boot component asks us, keep our protocol around - it will be used to
+ * validate further PE payloads (e.g.: by the UKI stub, before the kernel is booted).
+ * But also check that the variable was set by a boot component, to ensure that
+ * nobody at runtime can attempt to change shim's behaviour. */
+ efi_status = RT->GetVariable(SHIM_RETAIN_PROTOCOL_VAR_NAME,
+ &SHIM_LOCK_GUID,
+ &retain_protocol_attrs,
+ &retain_protocol_size,
+ &retain_protocol);
+ if (EFI_ERROR(efi_status) ||
+ (retain_protocol_attrs & EFI_VARIABLE_NON_VOLATILE) ||
+ !(retain_protocol_attrs & EFI_VARIABLE_BOOTSERVICE_ACCESS) ||
+ retain_protocol_size != sizeof(retain_protocol) ||
+ retain_protocol == 0)
+ uninstall_shim_protocols();
}
efi_status = BS->StartImage(image_handle, exit_data_size, exit_data);
if (EFI_ERROR(efi_status)) {
@@ -90,7 +109,7 @@ replacement_start_image(EFI_HANDLE image_handle, UINTN *exit_data_size, CHAR16 *
console_print(L"Something has gone seriously wrong: %r\n",
efi_status2);
console_print(L"shim cannot continue, sorry.\n");
- msleep(5000000);
+ usleep(5000000);
RT->ResetSystem(EfiResetShutdown,
EFI_SECURITY_VIOLATION,
0, NULL);
@@ -118,7 +137,7 @@ exit_boot_services(EFI_HANDLE image_key, UINTN map_key)
console_print(L"Bootloader has not verified loaded image.\n");
console_print(L"System is compromised. halting.\n");
- msleep(5000000);
+ usleep(5000000);
RT->ResetSystem(EfiResetShutdown, EFI_SECURITY_VIOLATION, 0, NULL);
return EFI_SECURITY_VIOLATION;
}
@@ -143,7 +162,7 @@ do_exit(EFI_HANDLE ImageHandle, EFI_STATUS ExitStatus,
console_print(L"Something has gone seriously wrong: %r\n",
efi_status2);
console_print(L"shim cannot continue, sorry.\n");
- msleep(5000000);
+ usleep(5000000);
RT->ResetSystem(EfiResetShutdown,
EFI_SECURITY_VIOLATION, 0, NULL);
}