From ee96dc367bc88d29b43e9c5dab91cb45dd360e2b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 16 Nov 2023 13:51:44 +0300 Subject: [PATCH] SecurePE: Turned ImageOrigin into function argument, added comments, introduced bits disabling protecion. --- .../DebugAgentSymbolsBaseLib.c | 5 ++- ArmVirtPkg/PrePi/PrePi.c | 5 ++- BaseTools/ImageTool/UefiImageScan.c | 5 ++- BaseTools/Source/C/Common/CommonLib.c | 5 ++- BaseTools/Source/C/EfiRom/EfiRom.c | 5 ++- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 23 ++++++------- .../FspWrapperNotifyDxe/LoadBelow4G.c | 5 ++- MdeModulePkg/Core/Dxe/DxeMain.h | 5 ++- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 5 ++- MdeModulePkg/Core/Dxe/Image/Image.c | 34 +++++++++++-------- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 12 ++++--- MdeModulePkg/Core/Pei/Image/Image.c | 10 +++--- MdeModulePkg/Core/Pei/Ppi/Ppi.c | 5 ++- MdeModulePkg/Core/PiSmmCore/Dispatcher.c | 5 ++- MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c | 5 ++- .../BootScriptExecutorDxe/ScriptExecute.c | 5 ++- MdePkg/Include/Library/PeCoffLib2.h | 4 +++ MdePkg/Include/Library/UefiImageLib.h | 14 +++++--- MdePkg/Library/BasePeCoffLib2/PeCoffInit.c | 14 ++++++-- .../Library/BaseUefiImageLib/CommonSupport.c | 6 ++-- MdePkg/Library/BaseUefiImageLib/PeSupport.c | 12 ++++--- MdePkg/Library/BaseUefiImageLib/UeSupport.c | 6 ++-- .../BaseUefiImageLib/UefiImageFormat.h | 6 ++-- .../Library/BaseUefiImageLib/UefiImageLib.c | 21 ++++++++---- MdePkg/MdePkg.dec | 3 ++ OvmfPkg/OvmfPkgIa32.dsc | 4 +-- OvmfPkg/Sec/SecMain.c | 8 ++--- .../CpuExceptionHandlerLib/PeiCpuException.c | 2 +- UefiCpuPkg/SecCore/FindPeiCore.c | 5 ++- UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c | 5 ++- 30 files changed, 139 insertions(+), 110 deletions(-) diff --git a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c index f08f46d575..1d25b82455 100644 --- a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c +++ b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c @@ -214,13 +214,12 @@ GetImageContext ( // Initialize the Image Context // FIXME: Common FFS API with size checks - ImageContext->ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( ImageContext, EfiImage, SectionLength - sizeof (*Section), - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (!EFI_ERROR(Status)) { Status = UefiImageLoadImageInplace( ImageContext); diff --git a/ArmVirtPkg/PrePi/PrePi.c b/ArmVirtPkg/PrePi/PrePi.c index 7d75c0e64b..d403279540 100644 --- a/ArmVirtPkg/PrePi/PrePi.c +++ b/ArmVirtPkg/PrePi/PrePi.c @@ -158,13 +158,12 @@ RelocateUefiImage ( Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SectionData, &SectionSize); ASSERT_EFI_ERROR (Status); - ImageContext.ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( &ImageContext, SectionData, SectionSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_RETURN_ERROR (Status); diff --git a/BaseTools/ImageTool/UefiImageScan.c b/BaseTools/ImageTool/UefiImageScan.c index d17efbd617..d9c4faafa4 100644 --- a/BaseTools/ImageTool/UefiImageScan.c +++ b/BaseTools/ImageTool/UefiImageScan.c @@ -205,13 +205,12 @@ ToolContextConstructUefiImage ( assert (File != NULL || FileSize == 0); - Context.ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( &Context, File, (UINT32)FileSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (RETURN_ERROR (Status)) { return Status; diff --git a/BaseTools/Source/C/Common/CommonLib.c b/BaseTools/Source/C/Common/CommonLib.c index 0ba49f59bf..08d4b6d81d 100644 --- a/BaseTools/Source/C/Common/CommonLib.c +++ b/BaseTools/Source/C/Common/CommonLib.c @@ -669,13 +669,12 @@ GetAlignmentFromFile ( CommonHeader = (EFI_COMMON_SECTION_HEADER *) ImageFileBuffer; CurSecHdrSize = GetSectionHeaderLength(CommonHeader); - ImageContext.ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( &ImageContext, ImageFileBuffer + CurSecHdrSize, ImageFileSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { Error (NULL, 0, 3000, "Invalid UefiImage", "The input file is %s and return status is %x", InFile, (int) Status); diff --git a/BaseTools/Source/C/EfiRom/EfiRom.c b/BaseTools/Source/C/EfiRom/EfiRom.c index ea1ea6e2f4..4929dac36b 100644 --- a/BaseTools/Source/C/EfiRom/EfiRom.c +++ b/BaseTools/Source/C/EfiRom/EfiRom.c @@ -836,13 +836,12 @@ Routine Description: RETURN_STATUS Status; UEFI_IMAGE_LOADER_IMAGE_CONTEXT Context; - Context.ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( &Context, FileBuffer, FileSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (RETURN_ERROR (Status)) { Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be an UEFI image - %llu!", Status); diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index 1676650a07..76e83a73d1 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -2514,13 +2514,12 @@ Routine Description: return EFI_INVALID_PARAMETER; } - Context.ImageOrigin = UefiImageOriginFv; - RETURN_STATUS Status = UefiImageInitializeContext ( &Context, UefiImage, UefiImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (RETURN_ERROR (Status)) { Error (NULL, 0, 3000, "Invalid", "Unrecognized UEFI image file."); @@ -3704,13 +3703,12 @@ Routine Description: // SectPeSize = GetSectionFileLength (CurrentPe32Section.CommonHeader) - CurSecHdrSize; - ImageContext.ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( &ImageContext, (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize), SectPeSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { Error (NULL, 0, 3000, "Invalid UefiImage", "The input file is %s and the return status is %x", FileName, (int) Status); @@ -3993,14 +3991,13 @@ Routine Description: // // Get this module function address from ModulePeMapFile and add them into FvMap file // - ImageContext.ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( - &ImageContext, - (VOID *) ((UINTN)(*FfsFile) + FileOffset), - RebasedImageSize, - UEFI_IMAGE_SOURCE_FV - ); + &ImageContext, + (VOID *) ((UINTN)(*FfsFile) + FileOffset), + RebasedImageSize, + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv + ); ASSERT_EFI_ERROR (Status); // diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c index 77644160e5..eac36f5d10 100644 --- a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c +++ b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c @@ -90,13 +90,12 @@ RelocateImageUnder4GIfNeeded ( // // Get information about the image being loaded // - ImageContext.ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( &ImageContext, Buffer, (UINT32) BufferSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); ImageSize = UefiImageGetImageSize (&ImageContext); diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index a27e7e8cb3..967b6eede6 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2720,14 +2720,13 @@ RemoveImageRecord ( Protect UEFI image. @param[in] LoadedImage The loaded image protocol - @param[in] ImageType Whether File comes from FV. Must be FALSE - or TRUE. + @param[in] ImageOrigin Where File comes from. @param[in] LoadedImageDevicePath The loaded image device path protocol **/ VOID ProtectUefiImage ( IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN BOOLEAN ImageIsFromFv, + IN UINT8 ImageOrigin, UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index e7b5b234f5..b4562d21e3 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -203,6 +203,7 @@ EFI_RUNTIME_SERVICES *gRT = &mEfiRuntimeServicesTableTemplate; EFI_HANDLE gImageHandle = NULL; BOOLEAN gMemoryMapTerminated = FALSE; +BOOLEAN gBdsStarted = FALSE; // // EFI Decompress Protocol @@ -318,7 +319,7 @@ DxeMain ( CoreInitializeMemoryProtection (); - ProtectUefiImage (&mCurrentImage->Info, TRUE, &ImageContext); + ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext); // // Call constructor for all libraries @@ -562,6 +563,8 @@ DxeMain ( (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT) ); + gBdsStarted = TRUE; + // // Transfer control to the BDS Architectural Protocol // diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index c8a9942e8c..c51cb77e30 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -24,6 +24,8 @@ STATIC LIST_ENTRY mAvailableEmulators; STATIC EFI_EVENT mPeCoffEmuProtocolRegistrationEvent; STATIC VOID *mPeCoffEmuProtocolNotifyRegistration; +extern BOOLEAN gBdsStarted; + // // This code is needed to build the Image handle for the DXE Core // @@ -1101,6 +1103,7 @@ CoreLoadImageCommon ( BOOLEAN ImageIsFromFv; BOOLEAN ImageIsFromLoadFile; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UINT8 ImageOrigin; SecurityStatus = EFI_SUCCESS; @@ -1171,8 +1174,8 @@ CoreLoadImageCommon ( Node = NULL; Status = CoreLocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &HandleFilePath, &DeviceHandle); if (!EFI_ERROR (Status)) { - ImageIsFromFv = TRUE; - ImageContext.ImageOrigin = UefiImageOriginFv; + ImageIsFromFv = TRUE; + ImageOrigin = UefiImageOriginFv; } else { HandleFilePath = FilePath; Status = CoreLocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &HandleFilePath, &DeviceHandle); @@ -1186,15 +1189,13 @@ CoreLoadImageCommon ( HandleFilePath = FilePath; Status = CoreLocateDevicePath (&gEfiLoadFileProtocolGuid, &HandleFilePath, &DeviceHandle); if (!EFI_ERROR (Status)) { - ImageIsFromLoadFile = TRUE; - Node = HandleFilePath; + ImageIsFromLoadFile = TRUE; + Node = HandleFilePath; } } - - ImageContext.ImageOrigin = UefiImageOriginOptionROM; - } else { - ImageContext.ImageOrigin = UefiImageOriginUserImage; } + + ImageOrigin = UefiImageOriginOptionROM; } // @@ -1223,6 +1224,10 @@ CoreLoadImageCommon ( goto Done; } + if (gBdsStarted) { + ImageOrigin = UefiImageOriginUserImage; + } + // // Get information about the image being loaded // @@ -1230,15 +1235,16 @@ CoreLoadImageCommon ( &ImageContext, FHand.Source, (UINT32) FHand.SourceSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + ImageOrigin ); if (Status == EFI_NOT_STARTED) { goto Done; } if (EFI_ERROR (Status)) { - ASSERT (FALSE); - return Status; + CpuDeadLoop (); + return Status; ///< Should be unreachable. } // FIXME: Context @@ -1298,8 +1304,8 @@ CoreLoadImageCommon ( Status = UefiImageInitializeContextPostHash (&ImageContext); if (EFI_ERROR (Status)) { - ASSERT (FALSE); - return Status; + CpuDeadLoop (); + return Status; ///< Should be unreachable. } // @@ -1427,7 +1433,7 @@ CoreLoadImageCommon ( } Status = EFI_SUCCESS; - ProtectUefiImage (&Image->Info, ImageIsFromFv, &ImageContext); + ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext); RegisterMemoryProfileImage ( Image->LoadedImageDevicePath, diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 6f41c62c8a..0a946ae535 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -10,7 +10,6 @@ requirement. 3) This policy is applied only if the Source UEFI image matches the PcdImageProtectionPolicy definition. - 4) This policy is not applied to the non-PE image region. The DxeCore calls CpuArchProtocol->SetMemoryAttributes() to protect the image. If the CpuArch protocol is not installed yet, the DxeCore @@ -164,14 +163,13 @@ IsMemoryProtectionSectionAligned ( Protect UEFI PE/COFF image. @param[in] LoadedImage The loaded image protocol - @param[in] ImageIsFromFv Whether File comes from FV. Must be FALSE - or TRUE. + @param[in] ImageOrigin Where File comes from. @param[in] LoadedImageDevicePath The loaded image device path protocol **/ VOID ProtectUefiImage ( IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN BOOLEAN ImageIsFromFv, + IN UINT8 ImageOrigin, UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { @@ -181,6 +179,12 @@ ProtectUefiImage ( CONST CHAR8 *PdbPointer; UINT32 PdbSize; BOOLEAN IsAligned; + // + // Do not protect images, if policy allows. + // + if ((mImageProtectionPolicy & (BIT30 >> ImageOrigin)) != 0) { + return; + } DEBUG ((DEBUG_INFO, "ProtectUefiImageCommon - 0x%x\n", LoadedImage)); DEBUG ((DEBUG_INFO, " - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase, LoadedImage->ImageSize)); diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c index 7889631e8d..772233fd97 100644 --- a/MdeModulePkg/Core/Pei/Image/Image.c +++ b/MdeModulePkg/Core/Pei/Image/Image.c @@ -195,13 +195,12 @@ LoadAndRelocateUefiImage ( ReturnStatus = EFI_SUCCESS; - ImageContext->ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( ImageContext, Pe32Data, Pe32DataSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { return Status; @@ -382,13 +381,12 @@ LoadAndRelocateUefiImageInPlace ( CopyMem (ImageAddress, Pe32Data, ImageSize); - ImageContext.ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( &ImageContext, ImageAddress, ImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c b/MdeModulePkg/Core/Pei/Ppi/Ppi.c index 0903273752..ab6cb2e16b 100644 --- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c +++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c @@ -1117,13 +1117,12 @@ ConvertPeiCorePpiPointers ( // Find PEI Core EntryPoint in the BFV in temporary memory. // // FIXME: "Assume" sanity and skip full initialisation? - ImageContext.ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( &ImageContext, (VOID *) (UINTN) PeiCoreImageBase, PeiCoreImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); diff --git a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c index 37dbeaeb8b..8f94e59178 100644 --- a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c +++ b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c @@ -339,13 +339,12 @@ SmmLoadImage ( // // Get information about the image being loaded // - ImageContext->ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContextPreHash ( ImageContext, Buffer, (UINT32) Size, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { if (Buffer != NULL) { diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c index 6870c80f4e..247037f5c4 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c @@ -1004,13 +1004,12 @@ ExecuteSmmCoreFromSmram ( // // Get information about the image being loaded // - gSmmCorePrivate->PiSmmCoreImageContext.ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( &gSmmCorePrivate->PiSmmCoreImageContext, SourceBuffer, (UINT32) SourceSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { return Status; diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c index 16c77864cb..812425c53f 100644 --- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c +++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c @@ -310,13 +310,12 @@ ReadyToLockEventNotify ( // // Get information about the image being loaded // - ImageContext.ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( &ImageContext, Buffer, (UINT32) BufferSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); diff --git a/MdePkg/Include/Library/PeCoffLib2.h b/MdePkg/Include/Library/PeCoffLib2.h index 3226ce5e94..18bb77236a 100644 --- a/MdePkg/Include/Library/PeCoffLib2.h +++ b/MdePkg/Include/Library/PeCoffLib2.h @@ -28,6 +28,10 @@ typedef enum { UefiImageOriginUserImage = 2, UefiImageOriginMax } UEFI_IMAGE_ORIGIN; +/// +/// If set, less than 4KB aligned image from firmware volume prevents boot. +/// +#define PCD_IMAGE_PROTECTION_POLICY_FV_STOP_BOOT BIT31 // FIXME: Where to put this? // diff --git a/MdePkg/Include/Library/UefiImageLib.h b/MdePkg/Include/Library/UefiImageLib.h index 930027c047..45a4423675 100644 --- a/MdePkg/Include/Library/UefiImageLib.h +++ b/MdePkg/Include/Library/UefiImageLib.h @@ -60,7 +60,6 @@ typedef UINT8 UEFI_IMAGE_SOURCE; typedef struct { UINT8 FormatIndex; - UINT8 ImageOrigin; union { UE_LOADER_IMAGE_CONTEXT Ue; PE_COFF_LOADER_IMAGE_CONTEXT Pe; @@ -150,7 +149,8 @@ UefiImageInitializeContextPreHash ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, IN UINT32 FileSize, - IN UEFI_IMAGE_SOURCE Source + IN UEFI_IMAGE_SOURCE Source, + IN UINT8 ImageOrigin ); RETURN_STATUS @@ -169,7 +169,9 @@ UefiImageInitializeContextPostHash ( @param[out] Context The context describing the Image. @param[in] FileBuffer The file data to parse as UEFI Image. @param[in] FileSize The size, in Bytes, of FileBuffer. - + @param[in] Source Determines supported loaders (PE/UE). + @param[in] ImageOrigin Determines image protection policy. + @retval RETURN_SUCCESS The Image context has been initialised successfully. @retval other The file data is malformed. **/ @@ -178,7 +180,8 @@ UefiImageInitializeContext ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, IN UINT32 FileSize, - IN UEFI_IMAGE_SOURCE Source + IN UEFI_IMAGE_SOURCE Source, + IN UINT8 ImageOrigin ); /** @@ -672,7 +675,8 @@ UefiImageLoaderGetImageRecord ( RETURN_STATUS UefiImageDebugLocateImage ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINTN Address + IN UINTN Address, + IN UINT8 ImageOrigin ); /** diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c b/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c index 1dc39eb334..321aac82f7 100644 --- a/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c @@ -481,12 +481,20 @@ InternalInitializePe ( DEBUG_RAISE (); return RETURN_VOLUME_CORRUPTED; } - + // + // Apply image protection policy + // if (Context->SectionAlignment < EFI_PAGE_SIZE) { Policy = PcdGet32 (PcdImageProtectionPolicy); - + // + // Images, which are less than 4KB aligned, won't be loaded, if policy demands. + // if ((Policy & (1U << ImageOrigin)) != 0) { - if (((Policy & BIT31) != 0) && (ImageOrigin == UefiImageOriginFv)) { + // + // Such an image from firmware volume will stop boot process, if policy orders. + // + if (((Policy & PCD_IMAGE_PROTECTION_POLICY_FV_STOP_BOOT) != 0) + && (ImageOrigin == UefiImageOriginFv)) { return RETURN_SECURITY_VIOLATION; } diff --git a/MdePkg/Library/BaseUefiImageLib/CommonSupport.c b/MdePkg/Library/BaseUefiImageLib/CommonSupport.c index 9355719ec2..154b867822 100644 --- a/MdePkg/Library/BaseUefiImageLib/CommonSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/CommonSupport.c @@ -19,7 +19,8 @@ UefiImageInitializeContext ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, IN UINT32 FileSize, - IN UEFI_IMAGE_SOURCE Source + IN UEFI_IMAGE_SOURCE Source, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -28,7 +29,8 @@ UefiImageInitializeContext ( Context, FileBuffer, FileSize, - Source + Source, + ImageOrigin ); if (RETURN_ERROR (Status)) { return Status; diff --git a/MdePkg/Library/BaseUefiImageLib/PeSupport.c b/MdePkg/Library/BaseUefiImageLib/PeSupport.c index 411faf66b1..aa027d343d 100644 --- a/MdePkg/Library/BaseUefiImageLib/PeSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/PeSupport.c @@ -27,10 +27,11 @@ RETURN_STATUS UefiImageInitializeContextPreHashPe ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UINT8 ImageOrigin ) { - return PeCoffInitializeContext (&Context->Ctx.Pe, FileBuffer, FileSize, Context->ImageOrigin); + return PeCoffInitializeContext (&Context->Ctx.Pe, FileBuffer, FileSize, ImageOrigin); } BOOLEAN @@ -614,7 +615,8 @@ InternalDebugLocateImage ( RETURN_STATUS UefiImageDebugLocateImagePe ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINTN Address + IN UINTN Address, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -645,7 +647,7 @@ UefiImageDebugLocateImagePe ( (CHAR8 *) (Address & ~(UINTN) 3U), Address, FALSE, - Context->ImageOrigin + ImageOrigin ); DEBUG_CODE_END (); @@ -714,7 +716,7 @@ UefiImageDebugPrintSegmentsPe ( Name = Sections[SectionIndex].Name; DEBUG (( DEBUG_VERBOSE, - " Section - '%c%c%c%c%c%c%c%c'\n", + " Section - '%c%c%c%c%c%c%c%c'\n" " VirtualSize - 0x%08x\n" " VirtualAddress - 0x%08x\n" " SizeOfRawData - 0x%08x\n" diff --git a/MdePkg/Library/BaseUefiImageLib/UeSupport.c b/MdePkg/Library/BaseUefiImageLib/UeSupport.c index 3e7c35d1ce..04a2f0d5fc 100644 --- a/MdePkg/Library/BaseUefiImageLib/UeSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/UeSupport.c @@ -37,7 +37,8 @@ RETURN_STATUS UefiImageInitializeContextPreHashUe ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UINT8 ImageOrigin ) { return UeInitializeContextPreHash (&Context->Ctx.Ue, FileBuffer, FileSize); @@ -433,7 +434,8 @@ UefiImageLoaderGetImageRecordUe ( RETURN_STATUS UefiImageDebugLocateImageUe ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINTN Address + IN UINTN Address, + IN UINT8 ImageOrigin ) { ASSERT (Context != NULL); diff --git a/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h b/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h index da64c5c462..88056571e7 100644 --- a/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h +++ b/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h @@ -18,7 +18,8 @@ RETURN_STATUS (*UEFI_IMAGE_INITIALIZE_CONTEXT_PRE_HASH) ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UINT8 ImageOrigin ); typedef @@ -192,7 +193,8 @@ typedef RETURN_STATUS (*UEFI_IMAGE_DEBUG_LOCATE_IMAGE) ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINTN Address + IN UINTN Address, + IN UINT8 ImageOrigin ); typedef diff --git a/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c b/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c index 5fb960cd4d..bc9f610fba 100644 --- a/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c +++ b/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c @@ -91,7 +91,8 @@ InternalInitializeContextPreHash ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, IN UINT32 FileSize, - IN UINT8 FormatIndex + IN UINT8 FormatIndex, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -102,7 +103,8 @@ InternalInitializeContextPreHash ( InitializeContextPreHash, Context, FileBuffer, - FileSize + FileSize, + ImageOrigin ); return Status; @@ -113,7 +115,8 @@ UefiImageInitializeContextPreHash ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, IN UINT32 FileSize, - IN UEFI_IMAGE_SOURCE Source + IN UEFI_IMAGE_SOURCE Source, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -144,7 +147,8 @@ UefiImageInitializeContextPreHash ( Context, FileBuffer, FileSize, - UefiImageFormatUe + UefiImageFormatUe, + ImageOrigin ); if (!RETURN_ERROR (Status)) { Context->FormatIndex = UefiImageFormatUe; @@ -157,7 +161,8 @@ UefiImageInitializeContextPreHash ( Context, FileBuffer, FileSize, - UefiImageFormatPe + UefiImageFormatPe, + ImageOrigin ); if (!RETURN_ERROR (Status)) { Context->FormatIndex = UefiImageFormatPe; @@ -626,7 +631,8 @@ UefiImageLoaderGetImageRecord ( RETURN_STATUS UefiImageDebugLocateImage ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINTN Address + IN UINTN Address, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -636,7 +642,8 @@ UefiImageDebugLocateImage ( Context->FormatIndex, DebugLocateImage, Context, - Address + Address, + ImageOrigin ); return Status; diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 000d5cad4e..2648ef4b45 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -2331,6 +2331,9 @@ # BIT2 - Images supplied by user.
#
# BIT31 - Firmware volume policy.
+ # BIT30 - Turn off protection for images from firmware volume.
+ # BIT29 - Turn off protection for images from option ROM.
+ # BIT28 - Turn off protection for images supplied by user.
# @Prompt Set image protection policy. gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000007|UINT32|0x40002002 diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 63436bfd01..9d18125c8a 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -585,8 +585,8 @@ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE !elseif $(WINDOWS_10_IA32) == TRUE # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiRuntimeServicesData memory regions. - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x0 - gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x0 + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF04 + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x70000000 !endif ################################################################################ diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c index e368cb7c2b..414d4331de 100644 --- a/OvmfPkg/Sec/SecMain.c +++ b/OvmfPkg/Sec/SecMain.c @@ -712,8 +712,6 @@ FindAndReportEntryPoints ( UINT32 PeiCoreImageSize; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; - ImageContext.ImageOrigin = UefiImageOriginFv; - // // Find SEC Core and PEI Core image base // @@ -729,7 +727,8 @@ FindAndReportEntryPoints ( &ImageContext, (VOID *) (UINTN) SecCoreImageBase, SecCoreImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); @@ -745,7 +744,8 @@ FindAndReportEntryPoints ( &ImageContext, (VOID *) (UINTN) PeiCoreImageBase, PeiCoreImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c index 47711b16b3..08c07758ef 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c @@ -227,7 +227,7 @@ GetImageInfoByIp ( UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UINT32 PdbPathSize; - Status = UefiImageDebugLocateImage (&ImageContext, CurrentEip); + Status = UefiImageDebugLocateImage (&ImageContext, CurrentEip, UefiImageOriginFv); if (RETURN_ERROR (Status)) { return FALSE; } diff --git a/UefiCpuPkg/SecCore/FindPeiCore.c b/UefiCpuPkg/SecCore/FindPeiCore.c index d740539efd..41cd4e8e65 100644 --- a/UefiCpuPkg/SecCore/FindPeiCore.c +++ b/UefiCpuPkg/SecCore/FindPeiCore.c @@ -169,13 +169,12 @@ FindAndReportEntryPoints ( ASSERT_EFI_ERROR (Status); // FIXME: DEBUG-only - ImageContext.ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( &ImageContext, (VOID*) (UINTN) SecCoreImageBase, SecCoreImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); diff --git a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c index d92d582efd..0a54e5d5de 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c +++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c @@ -36,13 +36,12 @@ LoadUefiImage ( UINT32 BufferSize; VOID *Buffer; - ImageContext.ImageOrigin = UefiImageOriginFv; - Status = UefiImageInitializeContext ( &ImageContext, UefiImage, UefiImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status);