diff --git a/MdeModulePkg/Universal/SecurityStubDxe/Defer3rdPartyImageLoad.c b/MdeModulePkg/Universal/SecurityStubDxe/Defer3rdPartyImageLoad.c index ca45d567bd..7135a9d87c 100644 --- a/MdeModulePkg/Universal/SecurityStubDxe/Defer3rdPartyImageLoad.c +++ b/MdeModulePkg/Universal/SecurityStubDxe/Defer3rdPartyImageLoad.c @@ -30,6 +30,7 @@ typedef struct { DEFERRED_3RD_PARTY_IMAGE_INFO *ImageInfo; ///< deferred 3rd party image item } DEFERRED_3RD_PARTY_IMAGE_TABLE; +BOOLEAN mImageLoadedAfterEndOfDxe = FALSE; BOOLEAN mEndOfDxe = FALSE; DEFERRED_3RD_PARTY_IMAGE_TABLE mDeferred3rdPartyImage = { 0, // Deferred image count @@ -256,6 +257,53 @@ EndOfDxe ( mEndOfDxe = TRUE; } +/** + Event notification for gEfiDxeSmmReadyToLockProtocolGuid event. + + This function reports failure if any deferred image is loaded before + this callback. + Platform should publish ReadyToLock protocol immediately after signaling + of the End of DXE Event. + + @param Event The Event that is being processed, not used. + @param Context Event Context, not used. + +**/ +VOID +EFIAPI +DxeSmmReadyToLock ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + VOID *Interface; + + Status = gBS->LocateProtocol (&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface); + if (EFI_ERROR (Status)) { + return; + } + + gBS->CloseEvent (Event); + + if (mImageLoadedAfterEndOfDxe) { + // + // Platform should not dispatch the 3rd party images after signaling EndOfDxe event + // but before publishing DxeSmmReadyToLock protocol. + // + DEBUG (( + DEBUG_ERROR, + "[Security] 3rd party images must be dispatched after DxeSmmReadyToLock Protocol installation!\n" + )); + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED, + (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE) + ); + ASSERT (FALSE); + CpuDeadLoop (); + } +} + /** Defer the 3rd party image load and installs Deferred Image Load Protocol. @@ -303,6 +351,7 @@ Defer3rdPartyImageLoad ( ); if (mEndOfDxe) { + mImageLoadedAfterEndOfDxe = TRUE; // // The image might be first time loaded after EndOfDxe, // So ImageInfo can be NULL. @@ -334,6 +383,7 @@ Defer3rdPartyImageLoadInitialize ( EFI_STATUS Status; EFI_HANDLE Handle; EFI_EVENT Event; + VOID *Registration; Handle = NULL; Status = gBS->InstallMultipleProtocolInterfaces ( @@ -353,4 +403,12 @@ Defer3rdPartyImageLoadInitialize ( &Event ); ASSERT_EFI_ERROR (Status); + + EfiCreateProtocolNotifyEvent ( + &gEfiDxeSmmReadyToLockProtocolGuid, + TPL_CALLBACK, + DxeSmmReadyToLock, + NULL, + &Registration + ); } diff --git a/MdeModulePkg/Universal/SecurityStubDxe/Defer3rdPartyImageLoad.h b/MdeModulePkg/Universal/SecurityStubDxe/Defer3rdPartyImageLoad.h index 3fab2582a7..75553bad3b 100644 --- a/MdeModulePkg/Universal/SecurityStubDxe/Defer3rdPartyImageLoad.h +++ b/MdeModulePkg/Universal/SecurityStubDxe/Defer3rdPartyImageLoad.h @@ -15,16 +15,19 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef _DEFER_3RD_PARTY_IMAGE_LOAD_H_ #define _DEFER_3RD_PARTY_IMAGE_LOAD_H_ -#include +#include #include #include #include +#include #include #include #include #include #include +#include +#include /** Returns information about a deferred image. diff --git a/MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf b/MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf index be6ce6c989..7f8f6cbb62 100644 --- a/MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf +++ b/MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf @@ -41,6 +41,8 @@ UefiBootServicesTableLib DebugLib SecurityManagementLib + ReportStatusCodeLib + UefiLib [Guids] gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event @@ -49,6 +51,7 @@ gEfiSecurityArchProtocolGuid ## PRODUCES gEfiSecurity2ArchProtocolGuid ## PRODUCES gEfiDeferredImageLoadProtocolGuid ## PRODUCES + gEfiDxeSmmReadyToLockProtocolGuid ## CONSUMES [Depex] TRUE