aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2023-05-19 17:40:51 +0100
committerMichael Brown <mcb30@ipxe.org>2023-05-19 17:40:51 +0100
commit7ec04b74167e53ea657f88b34e6fb74d165d0ccf (patch)
tree7bd691b6ebd94b78100004de301ff04df660ada2
parent6e85f25ca66f806ed6d87e503b09fe01df4f7831 (diff)
downloadipxe-7ec04b74167e53ea657f88b34e6fb74d165d0ccf.tar.gz
WIP - attempts to bypass shim lock
-rw-r--r--src/config/console.h2
-rw-r--r--src/image/efi_image.c9
-rw-r--r--src/include/ipxe/efi/efi_shim.h12
-rw-r--r--src/interface/efi/efi_shim.c78
4 files changed, 38 insertions, 63 deletions
diff --git a/src/config/console.h b/src/config/console.h
index 9f770d094..689e0519f 100644
--- a/src/config/console.h
+++ b/src/config/console.h
@@ -39,7 +39,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
//#define CONSOLE_SYSLOG /* Syslog console */
//#define CONSOLE_SYSLOGS /* Encrypted syslog console */
//#define CONSOLE_VMWARE /* VMware logfile console */
-//#define CONSOLE_DEBUGCON /* Bochs/QEMU/KVM debug port console */
+#define CONSOLE_DEBUGCON /* Bochs/QEMU/KVM debug port console */
//#define CONSOLE_INT13 /* INT13 disk log console */
/*
diff --git a/src/image/efi_image.c b/src/image/efi_image.c
index 13f08de28..d56f4cdd4 100644
--- a/src/image/efi_image.c
+++ b/src/image/efi_image.c
@@ -156,7 +156,6 @@ static int efi_image_exec ( struct image *image ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
struct efi_snp_device *snpdev;
EFI_DEVICE_PATH_PROTOCOL *path;
- struct efi_shim_unlocker unlocker;
union {
EFI_LOADED_IMAGE_PROTOCOL *image;
void *interface;
@@ -235,8 +234,7 @@ static int efi_image_exec ( struct image *image ) {
}
/* Install shim unlocker (if using a shim) */
- if ( shim &&
- ( ( rc = efi_shim_install ( &unlocker ) ) != 0 ) ) {
+ if ( shim && ( ( rc = efi_shim_install() ) != 0 ) ) {
DBGC ( image, "EFIIMAGE %s could not install shim unlocker: "
"%s\n", image->name, strerror ( rc ) );
goto err_shim_install;
@@ -295,6 +293,9 @@ static int efi_image_exec ( struct image *image ) {
/* Wrap calls made by the loaded image (for debugging) */
efi_wrap ( handle );
+ ///
+ DBG ( "***** loaded image systab %p\n", loaded.image->SystemTable );
+
/* Reset console since image will probably use it */
console_reset();
@@ -337,7 +338,7 @@ static int efi_image_exec ( struct image *image ) {
bs->UnloadImage ( handle );
err_load_image:
if ( shim )
- efi_shim_uninstall ( &unlocker );
+ efi_shim_uninstall();
err_shim_install:
free ( cmdline );
err_cmdline:
diff --git a/src/include/ipxe/efi/efi_shim.h b/src/include/ipxe/efi/efi_shim.h
index ec7803d66..6d146a4eb 100644
--- a/src/include/ipxe/efi/efi_shim.h
+++ b/src/include/ipxe/efi/efi_shim.h
@@ -12,18 +12,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/image.h>
#include <ipxe/efi/efi.h>
-/** A shim unlocker */
-struct efi_shim_unlocker {
- /** Protocol installation event */
- EFI_EVENT event;
- /** Protocol notification registration token */
- void *token;
-};
-
extern struct image_tag efi_shim __image_tag;
extern struct image_tag efi_shim_crutch __image_tag;
-extern int efi_shim_install ( struct efi_shim_unlocker *unlocker );
-extern void efi_shim_uninstall ( struct efi_shim_unlocker *unlocker );
+extern int efi_shim_install ( void );
+extern void efi_shim_uninstall ( void );
#endif /* _IPXE_EFI_SHIM_H */
diff --git a/src/interface/efi/efi_shim.c b/src/interface/efi/efi_shim.c
index b0caf227d..500a274a3 100644
--- a/src/interface/efi/efi_shim.c
+++ b/src/interface/efi/efi_shim.c
@@ -38,21 +38,25 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-/** EFI shim image */
+/** UEFI shim image */
struct image_tag efi_shim __image_tag = {
.name = "SHIM",
};
-/** EFI shim crutch image */
+/** UEFI shim crutch image */
struct image_tag efi_shim_crutch __image_tag = {
.name = "SHIMCRUTCH",
};
+/** Original ExitBootServices() function */
+static EFI_EXIT_BOOT_SERVICES efi_shim_orig_ebs;
+
/**
* Unlock UEFI shim
*
- * @v event Event
- * @v context Event context
+ * @v image Image handle
+ * @v key Map key
+ * @ret efirc EFI status code
*
* The UEFI shim is gradually becoming less capable of directly
* executing a kernel image, due to an ever increasing list of
@@ -68,77 +72,55 @@ struct image_tag efi_shim_crutch __image_tag = {
* this spurious requirement for the use of an additional second stage
* loader.
*/
-static EFIAPI void efi_shim_unlock ( EFI_EVENT event __unused, void *context ) {
+static EFIAPI EFI_STATUS efi_shim_unlock ( EFI_HANDLE image, UINTN key ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_GUID *protocol = &efi_shim_lock_protocol_guid;
- struct efi_shim_unlocker *unlocker = context;
+ uint8_t empty[0];
union {
EFI_SHIM_LOCK_PROTOCOL *lock;
void *interface;
} u;
- uint8_t empty[0];
EFI_STATUS efirc;
- /* Process all new instances of the shim lock protocol */
- while ( 1 ) {
+ //
+ DBG ( "******** called\n" );
- /* Get next instance */
- if ( ( efirc = bs->LocateProtocol ( protocol, unlocker->token,
- &u.interface ) ) != 0 )
- break;
-
- /* Call shim lock protocol with empty buffer */
+ /* Locate shim lock protocol */
+ if ( ( efirc = bs->LocateProtocol ( &efi_shim_lock_protocol_guid,
+ NULL, &u.interface ) ) == 0 ) {
u.lock->Verify ( empty, sizeof ( empty ) );
- DBGC ( unlocker, "SHIM unlocked %p\n", u.interface );
+ DBGC ( u.lock, "SHIM unlocked %p\n", u.lock );
}
+
+ /* Hand off to original ExitBootServices() */
+ return efi_shim_orig_ebs ( image, key );
}
/**
* Install UEFI shim unlocker
*
- * @v unlocker Shim unlocker
* @ret rc Return status code
*/
-int efi_shim_install ( struct efi_shim_unlocker *unlocker ) {
+int efi_shim_install ( ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_GUID *protocol = &efi_shim_lock_protocol_guid;
- EFI_STATUS efirc;
- int rc;
-
- /* Create event */
- if ( ( efirc = bs->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
- efi_shim_unlock, unlocker,
- &unlocker->event ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( unlocker, "SHIM could not create event: %s\n",
- strerror ( rc ) );
- goto err_create_event;
- }
- /* Register for protocol installations */
- if ( ( efirc = bs->RegisterProtocolNotify ( protocol, unlocker->event,
- &unlocker->token ) ) != 0){
- rc = -EEFI ( efirc );
- DBGC ( unlocker, "SHIM could not register for protocols: %s\n",
- strerror ( rc ) );
- goto err_register_notify;
- }
+ /* Intercept ExitBootServices() via boot services table */
+ efi_shim_orig_ebs = bs->ExitBootServices;
+ bs->ExitBootServices = efi_shim_unlock;
- return 0;
+ //
+ DBG ( "******** hooked in systab %p\n", efi_systab );
- err_register_notify:
- bs->CloseEvent ( unlocker->event );
- err_create_event:
- return rc;
+
+ return 0;
}
/**
* Uninstall UEFI shim unlocker
*
- * @v unlocker Shim unlocker
*/
-void efi_shim_uninstall ( struct efi_shim_unlocker *unlocker ) {
+void efi_shim_uninstall ( void ) {
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- bs->CloseEvent ( unlocker->event );
+ /* Restore original ExitBootServices() */
+ bs->ExitBootServices = efi_shim_orig_ebs;
}