diff options
| author | Peter Jones <pjones@redhat.com> | 2023-06-30 13:24:57 -0400 |
|---|---|---|
| committer | Peter Jones <pjones@redhat.com> | 2025-02-11 10:43:37 -0500 |
| commit | e7b3598311c4b002417ac6364093cfab218ced88 (patch) | |
| tree | 370ff1063bc624626a439303c6a2e27efd5a0e78 | |
| parent | bb114a3b92a96875dc71e5e4925bedba5c02f958 (diff) | |
| download | efi-boot-shim-e7b3598311c4b002417ac6364093cfab218ced88.tar.gz efi-boot-shim-e7b3598311c4b002417ac6364093cfab218ced88.zip | |
Move some stuff around
This moves some things around to help with loader protocol changes:
- Move replacements.c to loader-proto.c
- likewise with replacements.h
- move the SHIM_IMAGE_LOADER decl to loader-proto.h
- move the LoadImage / StartImage interface setup to an init function
- move shim_load_image() / shim_start_image() to loader-proto.c
Signed-off-by: Peter Jones <pjones@redhat.com>
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | globals.c | 2 | ||||
| -rw-r--r-- | include/loader-proto.h (renamed from include/replacements.h) | 9 | ||||
| -rw-r--r-- | loader-proto.c (renamed from replacements.c) | 94 | ||||
| -rw-r--r-- | shim.c | 91 | ||||
| -rw-r--r-- | shim.h | 11 |
6 files changed, 111 insertions, 100 deletions
@@ -38,9 +38,9 @@ CFLAGS += -DENABLE_SHIM_CERT else TARGETS += $(MMNAME) $(FBNAME) endif -OBJS = shim.o globals.o mok.o netboot.o cert.o dp.o replacements.o tpm.o version.o errlog.o sbat.o sbat_data.o sbat_var.o pe.o pe-relocate.o httpboot.o csv.o load-options.o utils.o +OBJS = shim.o globals.o mok.o netboot.o cert.o dp.o loader-proto.o tpm.o version.o errlog.o sbat.o sbat_data.o sbat_var.o pe.o pe-relocate.o httpboot.o csv.o load-options.o utils.o KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer -ORIG_SOURCES = shim.c globals.c mok.c netboot.c dp.c replacements.c tpm.c errlog.c sbat.c pe.c pe-relocate.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S sbat_var.S +ORIG_SOURCES = shim.c globals.c mok.c netboot.c dp.c loader-proto.c tpm.c errlog.c sbat.c pe.c pe-relocate.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S sbat_var.S MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o errlog.o sbat_data.o globals.o dp.o ORIG_MOK_SOURCES = MokManager.c PasswordCrypt.c crypt_blowfish.c shim.h $(wildcard include/*.h) FALLBACK_OBJS = fallback.o tpm.o errlog.o sbat_data.o globals.o utils.o @@ -26,6 +26,8 @@ UINT8 *build_cert; verification_method_t verification_method; int loader_is_participating; +SHIM_IMAGE_LOADER shim_image_loader_interface; + UINT8 user_insecure_mode; UINT8 ignore_db; UINT8 trust_mok_list; diff --git a/include/replacements.h b/include/loader-proto.h index 8b35c857..d3afa2f5 100644 --- a/include/replacements.h +++ b/include/loader-proto.h @@ -24,7 +24,12 @@ extern void unhook_system_services(void); extern void hook_exit(EFI_SYSTEM_TABLE *local_systab); extern void unhook_exit(void); -extern EFI_STATUS install_shim_protocols(void); -extern void uninstall_shim_protocols(void); +typedef struct _SHIM_IMAGE_LOADER { + EFI_IMAGE_LOAD LoadImage; + EFI_IMAGE_START StartImage; +} SHIM_IMAGE_LOADER; + +extern SHIM_IMAGE_LOADER shim_image_loader_interface; +extern void init_image_loader(void); #endif /* SHIM_REPLACEMENTS_H */ diff --git a/replacements.c b/loader-proto.c index d840616f..a61a91db 100644 --- a/replacements.c +++ b/loader-proto.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-2-Clause-Patent /* - * shim - trivial UEFI first-stage bootloader + * loader-proto.c - shim's loader protocol * * Copyright Red Hat, Inc */ @@ -54,6 +54,91 @@ unhook_system_services(void) } static EFI_STATUS EFIAPI +shim_load_image(BOOLEAN BootPolicy, EFI_HANDLE ParentImageHandle, + EFI_DEVICE_PATH *FilePath, VOID *SourceBuffer, + UINTN SourceSize, EFI_HANDLE *ImageHandle) +{ + SHIM_LOADED_IMAGE *image; + EFI_STATUS efi_status; + + (void)FilePath; + + if (BootPolicy || !SourceBuffer || !SourceSize) + return EFI_UNSUPPORTED; + + image = AllocatePool(sizeof(*image)); + if (!image) + return EFI_OUT_OF_RESOURCES; + + SetMem(image, sizeof(*image), 0); + + image->li.Revision = 0x1000; + image->li.ParentHandle = ParentImageHandle; + image->li.SystemTable = systab; + + efi_status = handle_image(SourceBuffer, SourceSize, &image->li, + &image->entry_point, &image->alloc_address, + &image->alloc_pages); + if (EFI_ERROR(efi_status)) + goto free_image; + + *ImageHandle = NULL; + efi_status = BS->InstallMultipleProtocolInterfaces(ImageHandle, + &SHIM_LOADED_IMAGE_GUID, image, + &EFI_LOADED_IMAGE_GUID, &image->li, + NULL); + if (EFI_ERROR(efi_status)) + goto free_alloc; + + return EFI_SUCCESS; + +free_alloc: + BS->FreePages(image->alloc_address, image->alloc_pages); +free_image: + FreePool(image); + return efi_status; +} + +static EFI_STATUS EFIAPI +shim_start_image(IN EFI_HANDLE ImageHandle, OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL) +{ + SHIM_LOADED_IMAGE *image; + EFI_STATUS efi_status; + + efi_status = BS->HandleProtocol(ImageHandle, &SHIM_LOADED_IMAGE_GUID, + (void **)&image); + if (EFI_ERROR(efi_status) || image->started) + return EFI_INVALID_PARAMETER; + + if (!setjmp(image->longjmp_buf)) { + image->started = true; + efi_status = + image->entry_point(ImageHandle, image->li.SystemTable); + } else { + if (ExitData) { + *ExitDataSize = image->exit_data_size; + *ExitData = (CHAR16 *)image->exit_data; + } + efi_status = image->exit_status; + } + + // + // We only support EFI applications, so we can unload and free the + // image unconditionally. + // + BS->UninstallMultipleProtocolInterfaces(ImageHandle, + &EFI_LOADED_IMAGE_GUID, image, + &SHIM_LOADED_IMAGE_GUID, &image->li, + NULL); + + BS->FreePages(image->alloc_address, image->alloc_pages); + FreePool(image); + + return efi_status; +} + +static EFI_STATUS EFIAPI load_image(BOOLEAN BootPolicy, EFI_HANDLE ParentImageHandle, EFI_DEVICE_PATH *DevicePath, VOID *SourceBuffer, UINTN SourceSize, EFI_HANDLE *ImageHandle) @@ -182,6 +267,13 @@ do_exit(EFI_HANDLE ImageHandle, EFI_STATUS ExitStatus, } void +init_image_loader(void) +{ + shim_image_loader_interface.LoadImage = shim_load_image; + shim_image_loader_interface.StartImage = shim_start_image; +} + +void hook_system_services(EFI_SYSTEM_TABLE *local_systab) { systab = local_systab; @@ -1314,7 +1314,6 @@ init_openssl(void) } static SHIM_LOCK shim_lock_interface; -static SHIM_IMAGE_LOADER shim_image_loader_interface; static EFI_HANDLE shim_lock_handle; EFI_STATUS @@ -1344,6 +1343,8 @@ install_shim_protocols(void) if (!EFI_ERROR(efi_status)) uninstall_shim_protocols(); + init_image_loader(); + /* * Install the protocol */ @@ -1915,91 +1916,6 @@ devel_egress(devel_egress_action action UNUSED) #endif } -static EFI_STATUS EFIAPI -shim_load_image(IN BOOLEAN BootPolicy, IN EFI_HANDLE ParentImageHandle, - IN EFI_DEVICE_PATH *FilePath, IN VOID *SourceBuffer, - IN UINTN SourceSize, OUT EFI_HANDLE *ImageHandle) -{ - SHIM_LOADED_IMAGE *image; - EFI_STATUS efi_status; - - (void)FilePath; - - if (BootPolicy || !SourceBuffer || !SourceSize) - return EFI_UNSUPPORTED; - - image = AllocatePool(sizeof(*image)); - if (!image) - return EFI_OUT_OF_RESOURCES; - - SetMem(image, sizeof(*image), 0); - - image->li.Revision = 0x1000; - image->li.ParentHandle = ParentImageHandle; - image->li.SystemTable = systab; - - efi_status = handle_image(SourceBuffer, SourceSize, &image->li, - &image->entry_point, &image->alloc_address, - &image->alloc_pages); - if (EFI_ERROR(efi_status)) - goto free_image; - - *ImageHandle = NULL; - efi_status = BS->InstallMultipleProtocolInterfaces(ImageHandle, - &SHIM_LOADED_IMAGE_GUID, image, - &EFI_LOADED_IMAGE_GUID, &image->li, - NULL); - if (EFI_ERROR(efi_status)) - goto free_alloc; - - return EFI_SUCCESS; - -free_alloc: - BS->FreePages(image->alloc_address, image->alloc_pages); -free_image: - FreePool(image); - return efi_status; -} - -static EFI_STATUS EFIAPI -shim_start_image(IN EFI_HANDLE ImageHandle, OUT UINTN *ExitDataSize, - OUT CHAR16 **ExitData OPTIONAL) -{ - SHIM_LOADED_IMAGE *image; - EFI_STATUS efi_status; - - efi_status = BS->HandleProtocol(ImageHandle, &SHIM_LOADED_IMAGE_GUID, - (void **)&image); - if (EFI_ERROR(efi_status) || image->started) - return EFI_INVALID_PARAMETER; - - if (!setjmp(image->longjmp_buf)) { - image->started = true; - efi_status = - image->entry_point(ImageHandle, image->li.SystemTable); - } else { - if (ExitData) { - *ExitDataSize = image->exit_data_size; - *ExitData = (CHAR16 *)image->exit_data; - } - efi_status = image->exit_status; - } - - // - // We only support EFI applications, so we can unload and free the - // image unconditionally. - // - BS->UninstallMultipleProtocolInterfaces(ImageHandle, - &EFI_LOADED_IMAGE_GUID, image, - &SHIM_LOADED_IMAGE_GUID, &image->li, - NULL); - - BS->FreePages(image->alloc_address, image->alloc_pages); - FreePool(image); - - return efi_status; -} - EFI_STATUS efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab) { @@ -2043,9 +1959,6 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab) shim_lock_interface.Hash = shim_hash; shim_lock_interface.Context = shim_read_header; - shim_image_loader_interface.LoadImage = shim_load_image; - shim_image_loader_interface.StartImage = shim_start_image; - systab = passed_systab; image_handle = global_image_handle = passed_image_handle; @@ -174,12 +174,12 @@ #include "include/ip4config2.h" #include "include/ip6config.h" #include "include/load-options.h" +#include "include/loader-proto.h" #include "include/mok.h" #include "include/netboot.h" #include "include/passwordcrypt.h" #include "include/peimage.h" #include "include/pe.h" -#include "include/replacements.h" #include "include/sbat.h" #include "include/sbat_var_defs.h" #include "include/ssp.h" @@ -238,11 +238,6 @@ typedef struct _SHIM_LOCK { EFI_SHIM_LOCK_CONTEXT Context; } SHIM_LOCK; -typedef struct _SHIM_IMAGE_LOADER { - EFI_IMAGE_LOAD LoadImage; - EFI_IMAGE_START StartImage; -} SHIM_IMAGE_LOADER; - extern EFI_STATUS shim_init(void); extern void shim_fini(void); extern EFI_STATUS EFIAPI LogError_(const char *file, int line, const char *func, @@ -256,6 +251,8 @@ extern VOID ClearErrors(VOID); extern VOID restore_loaded_image(VOID); extern EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath); extern EFI_STATUS import_mok_state(EFI_HANDLE image_handle); +extern EFI_STATUS install_shim_protocols(void); +extern void uninstall_shim_protocols(void); extern UINT32 vendor_authorized_size; extern UINT8 *vendor_authorized; @@ -332,6 +329,8 @@ verify_buffer (char *data, int datasize, char *translate_slashes(char *out, const char *str); +#include <efisetjmp_arch.h> + typedef struct { EFI_LOADED_IMAGE li; EFI_IMAGE_ENTRY_POINT entry_point; |
