diff options
author | Michael Brown <mcb30@ipxe.org> | 2023-05-19 17:40:51 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2023-05-19 17:40:51 +0100 |
commit | 7ec04b74167e53ea657f88b34e6fb74d165d0ccf (patch) | |
tree | 7bd691b6ebd94b78100004de301ff04df660ada2 | |
parent | 6e85f25ca66f806ed6d87e503b09fe01df4f7831 (diff) | |
download | ipxe-7ec04b74167e53ea657f88b34e6fb74d165d0ccf.tar.gz |
WIP - attempts to bypass shim lock
-rw-r--r-- | src/config/console.h | 2 | ||||
-rw-r--r-- | src/image/efi_image.c | 9 | ||||
-rw-r--r-- | src/include/ipxe/efi/efi_shim.h | 12 | ||||
-rw-r--r-- | src/interface/efi/efi_shim.c | 78 |
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; } |