diff options
author | Steve Langasek <steve.langasek@canonical.com> | 2019-02-09 21:28:06 -0800 |
---|---|---|
committer | Steve Langasek <steve.langasek@canonical.com> | 2019-02-09 21:32:44 -0800 |
commit | ab4c731c1dd379acd3e95971af57401fb0a650a1 (patch) | |
tree | 6a26fb8d0746cbbaa6c2d4b242c73442bcc1df06 /replacements.c | |
parent | 0d63079c7da8e86104ce4bbdae2f6cb8d2ea40c6 (diff) | |
parent | 9c12130f9cd2ae11a9336813dd1f1669c0b64ad0 (diff) | |
download | efi-boot-shim-debian/15+1533136590.3beb971-1.tar.gz efi-boot-shim-debian/15+1533136590.3beb971-1.zip |
* New upstream release.debian/15+1533136590.3beb971-1
- debian/patches/second-stage-path: dropped; the default loader path now
includes an arch suffix.
- debian/patches/sbsigntool-no-pesign: dropped; no longer needed.
* Drop remaining patches that were not being applied.
* Sync packaging from Ubuntu:
- debian/copyright: Update upstream source location.
- debian/control: add a Build-Depends on libelf-dev.
- Enable arm64 build.
- debian/patches/fixup_git.patch: don't run git in clean; we're not
really in a git tree.
- debian/rules, debian/shim.install: use the upstream install target as
intended, and move files to the target directory using dh_install.
- define RELEASE and COMMIT_ID for the snapshot.
- Set ENABLE_HTTPBOOT to enable the HTTP Boot feature.
- Update dh_auto_build/dh_auto_clean/dh_auto_install for new upstream
options: set MAKELEVEL.
- Define an EFI_ARCH variable, and use that for paths to shim. This
makes it possible to build a shim for other architectures than amd64.
- Set EFIDIR=$distro for dh_auto_install; that will let files be installed
in the "right" final directories, and makes boot.csv for us.
- Set ENABLE_SHIM_CERT, to keep using ephemeral self-signed certs built
at compile-time for MokManager and fallback.
- Set ENABLE_SBSIGN, to use sbsign instead of pesign for signing fallback
and MokManager.
Diffstat (limited to 'replacements.c')
-rw-r--r-- | replacements.c | 131 |
1 files changed, 62 insertions, 69 deletions
diff --git a/replacements.c b/replacements.c index 01eda0e3..944c779d 100644 --- a/replacements.c +++ b/replacements.c @@ -50,16 +50,19 @@ #include <efi.h> #include <efiapi.h> #include <efilib.h> -#include "shim.h" -#include "replacements.h" -/* oh for fuck's sakes.*/ -#ifndef EFI_SECURITY_VIOLATION -#define EFI_SECURITY_VIOLATION 26 -#endif +#include "shim.h" static EFI_SYSTEM_TABLE *systab; +EFI_SYSTEM_TABLE * +get_active_systab(void) +{ + if (systab) + return systab; + return ST; +} + static typeof(systab->BootServices->LoadImage) system_load_image; static typeof(systab->BootServices->StartImage) system_start_image; static typeof(systab->BootServices->Exit) system_exit; @@ -76,6 +79,7 @@ unhook_system_services(void) systab->BootServices->LoadImage = system_load_image; systab->BootServices->StartImage = system_start_image; systab->BootServices->ExitBootServices = system_exit_boot_services; + gBS = systab->BootServices; } static EFI_STATUS EFIAPI @@ -83,80 +87,67 @@ load_image(BOOLEAN BootPolicy, EFI_HANDLE ParentImageHandle, EFI_DEVICE_PATH *DevicePath, VOID *SourceBuffer, UINTN SourceSize, EFI_HANDLE *ImageHandle) { - EFI_STATUS status; - unhook_system_services(); + EFI_STATUS efi_status; - status = systab->BootServices->LoadImage(BootPolicy, - ParentImageHandle, DevicePath, - SourceBuffer, SourceSize, ImageHandle); + unhook_system_services(); + efi_status = gBS->LoadImage(BootPolicy, ParentImageHandle, DevicePath, + SourceBuffer, SourceSize, ImageHandle); hook_system_services(systab); - if (EFI_ERROR(status)) + if (EFI_ERROR(efi_status)) last_loaded_image = NULL; else last_loaded_image = *ImageHandle; - return status; + return efi_status; } static EFI_STATUS EFIAPI -start_image(EFI_HANDLE image_handle, UINTN *exit_data_size, CHAR16 **exit_data) +replacement_start_image(EFI_HANDLE image_handle, UINTN *exit_data_size, CHAR16 **exit_data) { - EFI_STATUS status; + EFI_STATUS efi_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)) { + efi_status = gBS->StartImage(image_handle, exit_data_size, exit_data); + if (EFI_ERROR(efi_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); + EFI_STATUS efi_status2 = install_shim_protocols(); + + if (EFI_ERROR(efi_status2)) { + console_print(L"Something has gone seriously wrong: %r\n", + efi_status2); + console_print(L"shim cannot continue, sorry.\n"); + msleep(5000000); + gRT->ResetSystem(EfiResetShutdown, + EFI_SECURITY_VIOLATION, + 0, NULL); } } hook_system_services(systab); loader_is_participating = 0; } - return status; + return efi_status; } static EFI_STATUS EFIAPI exit_boot_services(EFI_HANDLE image_key, UINTN map_key) { - if (loader_is_participating || verification_method == VERIFIED_BY_HASH) { + 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) + EFI_STATUS efi_status; + efi_status = gBS->ExitBootServices(image_key, map_key); + if (EFI_ERROR(efi_status)) hook_system_services(systab); - return status; + return efi_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); + console_print(L"Bootloader has not verified loaded image.\n"); + console_print(L"System is compromised. halting.\n"); + msleep(5000000); + gRT->ResetSystem(EfiResetShutdown, EFI_SECURITY_VIOLATION, 0, NULL); return EFI_SECURITY_VIOLATION; } @@ -164,41 +155,41 @@ static EFI_STATUS EFIAPI do_exit(EFI_HANDLE ImageHandle, EFI_STATUS ExitStatus, UINTN ExitDataSize, CHAR16 *ExitData) { - EFI_STATUS status; + EFI_STATUS efi_status; 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); + efi_status = gBS->Exit(ImageHandle, ExitStatus, + ExitDataSize, ExitData); + if (EFI_ERROR(efi_status)) { + EFI_STATUS efi_status2 = shim_init(); + + if (EFI_ERROR(efi_status2)) { + console_print(L"Something has gone seriously wrong: %r\n", + efi_status2); + console_print(L"shim cannot continue, sorry.\n"); + msleep(5000000); + gRT->ResetSystem(EfiResetShutdown, + EFI_SECURITY_VIOLATION, 0, NULL); } } - return status; + return efi_status; } void hook_system_services(EFI_SYSTEM_TABLE *local_systab) { systab = local_systab; + gBS = systab->BootServices; /* We need to hook various calls to make this work... */ /* 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 - * and mark loader_is_participating in start_image. This means - * anything added by fallback has to be verified by the system db, - * which we want to preserve anyway, since that's all launching + * and mark loader_is_participating in replacement_start_image. This + * means anything added by fallback has to be verified by the system + * db, which we want to preserve anyway, since that's all launching * through BDS gives us. */ system_load_image = systab->BootServices->LoadImage; systab->BootServices->LoadImage = load_image; @@ -206,7 +197,7 @@ hook_system_services(EFI_SYSTEM_TABLE *local_systab) /* we need StartImage() so that we can allow chain booting to an * image trusted by the firmware */ system_start_image = systab->BootServices->StartImage; - systab->BootServices->StartImage = start_image; + systab->BootServices->StartImage = replacement_start_image; /* we need to hook ExitBootServices() so a) we can enforce the policy * and b) we can unwrap when we're done. */ @@ -218,12 +209,14 @@ void unhook_exit(void) { systab->BootServices->Exit = system_exit; + gBS = systab->BootServices; } void hook_exit(EFI_SYSTEM_TABLE *local_systab) { systab = local_systab; + gBS = local_systab->BootServices; /* 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 |