summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--globals.c2
-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.c91
-rw-r--r--shim.h11
6 files changed, 111 insertions, 100 deletions
diff --git a/Makefile b/Makefile
index 1c3190b9..bf339fab 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/globals.c b/globals.c
index b4e80dd3..91916e98 100644
--- a/globals.c
+++ b/globals.c
@@ -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;
diff --git a/shim.c b/shim.c
index 60b5e720..98462aa0 100644
--- a/shim.c
+++ b/shim.c
@@ -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;
diff --git a/shim.h b/shim.h
index 704e34ea..a3f8a505 100644
--- a/shim.h
+++ b/shim.h
@@ -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;