static EFI_STATUS EFIAPI start_image(EFI_HANDLE image_handle, UINTN *exit_data_size, CHAR16 **exit_data) { EFI_STATUS status; unhook_system_services(); status = systab->BootServices->StartImage(image_handle, exit_data_size, exit_data); if (EFI_ERROR(status)) hook_system_services(systab); return status; }
static EFI_STATUS EFIAPI efi_exit(EFI_HANDLE ImageHandle, EFI_STATUS ExitStatus, 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); return status; }
static EFI_STATUS EFIAPI exit_boot_services(EFI_HANDLE image_key, UINTN map_key) { if (loader_is_participating || verification_method == VERIFIED_BY_HASH) { unhook_system_services(); EFI_STATUS status; status = systab->BootServices->ExitBootServices(image_key, map_key); if (status != EFI_SUCCESS) hook_system_services(systab); return status; } Print(L"Bootloader has not verified loaded image.\n"); Print(L"System is compromised. halting.\n"); systab->BootServices->Stall(5000000); systab->RuntimeServices->ResetSystem(EfiResetShutdown, EFI_SECURITY_VIOLATION, 0, NULL); return EFI_SECURITY_VIOLATION; }
static EFI_STATUS EFIAPI load_image(BOOLEAN BootPolicy, EFI_HANDLE ParentImageHandle, EFI_DEVICE_PATH *DevicePath, VOID *SourceBuffer, UINTN SourceSize, EFI_HANDLE *ImageHandle) { EFI_STATUS status; unhook_system_services(); status = systab->BootServices->LoadImage(BootPolicy, ParentImageHandle, DevicePath, SourceBuffer, SourceSize, ImageHandle); hook_system_services(systab); if (EFI_ERROR(status)) last_loaded_image = NULL; else last_loaded_image = *ImageHandle; return status; }
static EFI_STATUS EFIAPI start_image(EFI_HANDLE image_handle, UINTN *exit_data_size, CHAR16 **exit_data) { EFI_STATUS status; unhook_system_services(); /* We have to uninstall shim's protocol here, because if we're * On the fallback.efi path, then our call pathway is: * * shim->fallback->shim->grub * ^ ^ ^ * | | \- gets protocol #0 * | \- installs its protocol (#1) * \- installs its protocol (#0) * and if we haven't removed this, then grub will get the *first* * shim's protocol, but it'll get the second shim's systab * replacements. So even though it will participate and verify * the kernel, the systab never finds out. */ if (image_handle == last_loaded_image) { loader_is_participating = 1; uninstall_shim_protocols(); } status = systab->BootServices->StartImage(image_handle, exit_data_size, exit_data); if (EFI_ERROR(status)) { if (image_handle == last_loaded_image) { EFI_STATUS status2 = install_shim_protocols(); if (EFI_ERROR(status2)) { Print(L"Something has gone seriously wrong: %d\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); loader_is_participating = 0; } return status; }