From 46050fc0fcd4745544a2b522de8af45634015f22 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 1 Jul 2024 12:24:47 +0300 Subject: [PATCH] SecurePE: Defined new PcdImageProtectionPolicy. --- .../DebugAgentSymbolsBaseLib.c | 3 +- ArmVirtPkg/ArmVirt.dsc.inc | 6 -- ArmVirtPkg/PrePi/PrePi.c | 3 +- BaseTools/ImageTool/ImageTool.c | 6 +- BaseTools/ImageTool/UefiImageScan.c | 3 +- BaseTools/Source/C/Common/CommonLib.c | 3 +- BaseTools/Source/C/EfiRom/EfiRom.c | 3 +- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 19 ++-- BaseTools/Source/C/Include/Common/AutoGen.h | 6 ++ EmbeddedPkg/Library/PrePiLib/PrePiLib.c | 3 +- EmulatorPkg/EmulatorPkg.dsc | 2 +- .../FspWrapperNotifyDxe/LoadBelow4G.c | 3 +- MdeModulePkg/Core/Dxe/DxeMain.h | 5 +- MdeModulePkg/Core/Dxe/DxeMain.inf | 3 +- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 5 +- MdeModulePkg/Core/Dxe/Image/Image.c | 31 ++++-- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 94 +++---------------- MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +- MdeModulePkg/Core/Pei/Image/Image.c | 6 +- MdeModulePkg/Core/Pei/Ppi/Ppi.c | 3 +- MdeModulePkg/Core/PiSmmCore/Dispatcher.c | 3 +- MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c | 3 +- MdeModulePkg/MdeModulePkg.dec | 15 --- MdeModulePkg/MdeModulePkg.uni | 12 --- .../BootScriptExecutorDxe/ScriptExecute.c | 3 +- MdePkg/Include/Library/PeCoffLib2.h | 14 ++- MdePkg/Include/Library/UefiImageLib.h | 13 ++- .../Library/BasePeCoffLib2/BasePeCoffLib2.inf | 1 + MdePkg/Library/BasePeCoffLib2/PeCoffInit.c | 29 +++++- .../Library/BaseUefiImageLib/CommonSupport.c | 6 +- MdePkg/Library/BaseUefiImageLib/PeSupport.c | 22 +++-- MdePkg/Library/BaseUefiImageLib/UeSupport.c | 6 +- .../BaseUefiImageLib/UefiImageFormat.h | 6 +- .../Library/BaseUefiImageLib/UefiImageLib.c | 21 +++-- MdePkg/MdePkg.dec | 21 +++++ OvmfPkg/IntelTdx/IntelTdxX64.dsc | 1 + .../PeilessStartupLib/PeilessStartupLib.inf | 2 +- OvmfPkg/OvmfPkgIa32.dsc | 3 +- OvmfPkg/OvmfPkgIa32X64.dsc | 6 +- OvmfPkg/OvmfPkgX64.dsc | 1 + OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc | 6 -- OvmfPkg/Sec/SecMain.c | 6 +- .../CpuExceptionHandlerLib/PeiCpuException.c | 2 +- UefiCpuPkg/SecCore/FindPeiCore.c | 6 +- UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c | 3 +- .../UefiPayloadEntry/UefiPayloadEntry.inf | 2 +- .../UniversalPayloadEntry.inf | 2 +- 47 files changed, 225 insertions(+), 199 deletions(-) diff --git a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c index 525483a440..1d25b82455 100644 --- a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c +++ b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c @@ -218,7 +218,8 @@ GetImageContext ( 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/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 5f9387c5c4..2881475b80 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -373,12 +373,6 @@ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20 gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0 - # - # Enable strict image permissions for all images. (This applies - # only to images that were built with >= 4 KB section alignment.) - # - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x3 - # # Enable NX memory protection for all non-code regions, including OEM and OS # reserved ones, with the exception of LoaderData regions, of which OS loaders diff --git a/ArmVirtPkg/PrePi/PrePi.c b/ArmVirtPkg/PrePi/PrePi.c index deda3fe7bb..3d44b44c20 100644 --- a/ArmVirtPkg/PrePi/PrePi.c +++ b/ArmVirtPkg/PrePi/PrePi.c @@ -156,7 +156,8 @@ RelocateUefiImage ( &ImageContext, SectionData, SectionSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_RETURN_ERROR (Status); diff --git a/BaseTools/ImageTool/ImageTool.c b/BaseTools/ImageTool/ImageTool.c index d3a4378e5c..7734228141 100644 --- a/BaseTools/ImageTool/ImageTool.c +++ b/BaseTools/ImageTool/ImageTool.c @@ -250,7 +250,7 @@ GetAcpi ( return RETURN_ABORTED; } - Status = PeCoffInitializeContext (&Context, Pe, (UINT32)PeSize); + Status = PeCoffInitializeContext (&Context, Pe, (UINT32)PeSize, UefiImageOriginFv); if (RETURN_ERROR (Status)) { fprintf (stderr, "ImageTool: Could not initialise Context\n"); free (Pe); @@ -442,6 +442,10 @@ int main (int argc, const char *argv[]) bool FixedAddress; int ArgIndex; + PcdGet8 (PcdUefiImageFormatSupportNonFv) = 0x00; + PcdGet8 (PcdUefiImageFormatSupportFv) = 0x03; + PcdGet32 (PcdImageProtectionPolicy) = 0x00; + if (argc < 2) { fprintf (stderr, "ImageTool: No command is specified\n"); DEBUG_RAISE (); diff --git a/BaseTools/ImageTool/UefiImageScan.c b/BaseTools/ImageTool/UefiImageScan.c index bbf791f703..d9c4faafa4 100644 --- a/BaseTools/ImageTool/UefiImageScan.c +++ b/BaseTools/ImageTool/UefiImageScan.c @@ -209,7 +209,8 @@ ToolContextConstructUefiImage ( &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 98176555af..08d4b6d81d 100644 --- a/BaseTools/Source/C/Common/CommonLib.c +++ b/BaseTools/Source/C/Common/CommonLib.c @@ -673,7 +673,8 @@ GetAlignmentFromFile ( &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 053849202a..4929dac36b 100644 --- a/BaseTools/Source/C/EfiRom/EfiRom.c +++ b/BaseTools/Source/C/EfiRom/EfiRom.c @@ -840,7 +840,8 @@ Returns: &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 1d430115c7..3b7d90e5db 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -2395,7 +2395,8 @@ Returns: &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."); @@ -3578,11 +3579,13 @@ Returns: // Initialize context // SectPeSize = GetSectionFileLength (CurrentPe32Section.CommonHeader) - CurSecHdrSize; + 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); @@ -3865,13 +3868,13 @@ Returns: // // Get this module function address from ModulePeMapFile and add them into FvMap file // - 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/BaseTools/Source/C/Include/Common/AutoGen.h b/BaseTools/Source/C/Include/Common/AutoGen.h index 8b5f42bd03..c9af984cc8 100644 --- a/BaseTools/Source/C/Include/Common/AutoGen.h +++ b/BaseTools/Source/C/Include/Common/AutoGen.h @@ -177,6 +177,12 @@ extern UINT64 _gPcd_SkuId_Array[]; #define _PCD_GET_MODE_8_PcdUefiImageFormatSupportFv _PCD_VALUE_PcdUefiImageFormatSupportFv //#define _PCD_SET_MODE_8_PcdUefiImageFormatSupportFv ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD +#define _PCD_TOKEN_PcdImageProtectionPolicy 0U +#define _PCD_SIZE_PcdImageProtectionPolicy 4 +#define _PCD_GET_MODE_SIZE_PcdImageProtectionPolicy _PCD_SIZE_PcdImageProtectionPolicy +#define _PCD_VALUE_PcdImageProtectionPolicy 0U +#define _PCD_GET_MODE_32_PcdImageProtectionPolicy _PCD_VALUE_PcdImageProtectionPolicy +//#define _PCD_SET_MODE_32_PcdImageProtectionPolicy ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD #ifdef __cplusplus } diff --git a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c index 9826e9493e..c94dc0d45a 100644 --- a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c +++ b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c @@ -44,7 +44,8 @@ LoadUefiImage ( &ImageContext, UefiImage, UefiImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc index b0f57fa461..ab1feb3c8f 100644 --- a/EmulatorPkg/EmulatorPkg.dsc +++ b/EmulatorPkg/EmulatorPkg.dsc @@ -214,7 +214,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables|FALSE [PcdsFixedAtBuild] - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000000 + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000000 gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000040 gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x0f diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c index 55ee2c6f9a..eac36f5d10 100644 --- a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c +++ b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c @@ -94,7 +94,8 @@ RelocateImageUnder4GIfNeeded ( &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 8812c32394..2821b6c2ef 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2725,14 +2725,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.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 8669c1dc6f..681ad580a2 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -183,7 +183,6 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileMemoryType ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfilePropertyMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType ## CONSUMES @@ -192,6 +191,8 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdImageLargeAddressLoad ## CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask ## CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES # [Hob] # RESOURCE_DESCRIPTOR ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 0974d85570..963c44c8f7 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 @@ -323,7 +324,7 @@ DxeMain ( CoreInitializeMemoryProtection (); - ProtectUefiImage (&mCurrentImage->Info, TRUE, &ImageContext); + ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext); // // Call constructor for all libraries @@ -566,6 +567,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 69297b0a4d..ff3e9f5f06 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,11 +1103,13 @@ CoreLoadImageCommon ( BOOLEAN ImageIsFromFv; BOOLEAN ImageIsFromLoadFile; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UINT8 ImageOrigin; SecurityStatus = EFI_SUCCESS; ASSERT (gEfiCurrentTpl < TPL_NOTIFY); ParentImage = NULL; + Image = NULL; // // The caller must pass in a valid ParentImageHandle @@ -1171,6 +1175,7 @@ CoreLoadImageCommon ( Status = CoreLocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &HandleFilePath, &DeviceHandle); if (!EFI_ERROR (Status)) { ImageIsFromFv = TRUE; + ImageOrigin = UefiImageOriginFv; } else { HandleFilePath = FilePath; Status = CoreLocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &HandleFilePath, &DeviceHandle); @@ -1189,6 +1194,8 @@ CoreLoadImageCommon ( } } } + + ImageOrigin = UefiImageOriginOptionROM; } // @@ -1214,10 +1221,13 @@ CoreLoadImageCommon ( } if (EFI_ERROR (Status)) { - Image = NULL; goto Done; } + if (gBdsStarted) { + ImageOrigin = UefiImageOriginUserImage; + } + // // Get information about the image being loaded // @@ -1225,11 +1235,15 @@ CoreLoadImageCommon ( &ImageContext, FHand.Source, (UINT32) FHand.SourceSize, - ImageIsFromFv ? UEFI_IMAGE_SOURCE_FV : UEFI_IMAGE_SOURCE_NON_FV + ImageIsFromFv ? UEFI_IMAGE_SOURCE_FV : UEFI_IMAGE_SOURCE_NON_FV, + ImageOrigin ); if (EFI_ERROR (Status)) { - ASSERT (FALSE); - return Status; + if ((ImageOrigin != UefiImageOriginUserImage) && (Status != EFI_NOT_STARTED)) { + CpuDeadLoop (); + } + + goto Done; } // FIXME: Context @@ -1284,12 +1298,15 @@ CoreLoadImageCommon ( } Status = SecurityStatus; - Image = NULL; goto Done; } Status = UefiImageInitializeContextPostHash (&ImageContext); - if (RETURN_ERROR (Status)) { + if (EFI_ERROR (Status)) { + if (ImageOrigin != UefiImageOriginUserImage) { + CpuDeadLoop (); + } + goto Done; } @@ -1418,7 +1435,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 5692900e2d..5b0fe44a23 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 @@ -47,12 +46,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "ProcessorBind.h" #include "Uefi/UefiMultiPhase.h" -// -// Protection policy bit definition -// -#define DO_NOT_PROTECT 0x00000000 -#define PROTECT_IF_ALIGNED_ELSE_ALLOW 0x00000001 - #define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 #define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 @@ -65,58 +58,6 @@ extern LIST_ENTRY mGcdMemorySpaceMap; STATIC LIST_ENTRY mProtectedImageRecordList; -/** - Get UEFI image protection policy based upon image type. - - @param[in] ImageIsFromFv Whether File comes from FV. Must be FALSE or TRUE. - - @return UEFI image protection policy -**/ -UINT32 -GetProtectionPolicyFromImageType ( - IN BOOLEAN ImageIsFromFv - ) -{ - ASSERT (ImageIsFromFv == FALSE || ImageIsFromFv == TRUE); - - if (((ImageIsFromFv + 1) & mImageProtectionPolicy) == 0) { - return DO_NOT_PROTECT; - } else { - return PROTECT_IF_ALIGNED_ELSE_ALLOW; - } -} - -/** - Get UEFI image protection policy based upon loaded image device path. - - @param[in] ImageIsFromFv Whether File comes from FV. Must be FALSE or TRUE. - - @return UEFI image protection policy -**/ -UINT32 -GetUefiImageProtectionPolicy ( - IN BOOLEAN ImageIsFromFv - ) -{ - BOOLEAN InSmm; - UINT32 ProtectionPolicy; - - // - // Check SMM - // - InSmm = FALSE; - if (gSmmBase2 != NULL) { - gSmmBase2->InSmm (gSmmBase2, &InSmm); - } - - if (InSmm) { - return FALSE; - } - - ProtectionPolicy = GetProtectionPolicyFromImageType (ImageIsFromFv); - return ProtectionPolicy; -} - /** Set UEFI image memory attributes. @@ -224,39 +165,32 @@ 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 ) { - RETURN_STATUS PdbStatus; - UINT32 SectionAlignment; - UEFI_IMAGE_RECORD *ImageRecord; - CONST CHAR8 *PdbPointer; - UINT32 PdbSize; - BOOLEAN IsAligned; - UINT32 ProtectionPolicy; + RETURN_STATUS PdbStatus; + UINT32 SectionAlignment; + UEFI_IMAGE_RECORD *ImageRecord; + 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)); - ProtectionPolicy = GetUefiImageProtectionPolicy (ImageIsFromFv); - switch (ProtectionPolicy) { - case DO_NOT_PROTECT: - return; - case PROTECT_IF_ALIGNED_ELSE_ALLOW: - break; - default: - ASSERT (FALSE); - return; - } - PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbSize); if (!RETURN_ERROR (PdbStatus)) { DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer)); diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf index 1473be8f95..e231e7bd6f 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -112,7 +112,7 @@ [Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c index a32f1b949a..772233fd97 100644 --- a/MdeModulePkg/Core/Pei/Image/Image.c +++ b/MdeModulePkg/Core/Pei/Image/Image.c @@ -199,7 +199,8 @@ LoadAndRelocateUefiImage ( ImageContext, Pe32Data, Pe32DataSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { return Status; @@ -384,7 +385,8 @@ LoadAndRelocateUefiImageInPlace ( &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 0ea343c252..ab6cb2e16b 100644 --- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c +++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c @@ -1121,7 +1121,8 @@ ConvertPeiCorePpiPointers ( &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 fb0e861463..64d1e359f8 100644 --- a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c +++ b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c @@ -343,7 +343,8 @@ SmmLoadImage ( 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 b3ca963049..247037f5c4 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c @@ -1008,7 +1008,8 @@ ExecuteSmmCoreFromSmram ( &gSmmCorePrivate->PiSmmCoreImageContext, SourceBuffer, (UINT32) SourceSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { return Status; diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 7935f65b2d..e8b0bbb847 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -1414,21 +1414,6 @@ # @Prompt Memory profile driver path. gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath|{0x0}|VOID*|0x00001043 - ## Set image protection policy. The policy is bitwise. - # If a bit is set, the image will be protected by DxeCore if it is aligned. - # The code section becomes read-only, and the data section becomes non-executable. - # If a bit is clear, nothing will be done to image code/data sections.

- # BIT0 - Image from unknown device.
- # BIT1 - Image from firmware volume.
- #
- # Note: If a bit is cleared, the data section could be still non-executable if - # PcdDxeNxMemoryProtectionPolicy is enabled for EfiLoaderData, EfiBootServicesData - # and/or EfiRuntimeServicesData.
- #
- # @Prompt Set image protection policy. - # @ValidRange 0x80000002 | 0x00000000 - 0x0000001F - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000002|UINT32|0x00001047 - ## Set DXE memory protection policy. The policy is bitwise. # If a bit is set, memory regions of the associated type will be mapped # non-executable.
diff --git a/MdeModulePkg/MdeModulePkg.uni b/MdeModulePkg/MdeModulePkg.uni index 7124f07a71..a5b7d87483 100644 --- a/MdeModulePkg/MdeModulePkg.uni +++ b/MdeModulePkg/MdeModulePkg.uni @@ -1098,18 +1098,6 @@ #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdSmiHandlerProfilePropertyMask_HELP #language en-US "The mask is used to control SmiHandlerProfile behavior.

\n" "BIT0 - Enable SmiHandlerProfile.
" -#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdImageProtectionPolicy_PROMPT #language en-US "Set image protection policy." - -#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdImageProtectionPolicy_HELP #language en-US "Set image protection policy. The policy is bitwise.\n" - "If a bit is set, the image will be protected by DxeCore if it is aligned.\n" - "The code section becomes read-only, and the data section becomes non-executable.\n" - "If a bit is clear, nothing will be done to image code/data sections.

\n" - "BIT0 - Image from unknown device.
\n" - "BIT1 - Image from firmware volume.
" - "Note: If a bit is cleared, the data section could be still non-executable if\n" - "PcdDxeNxMemoryProtectionPolicy is enabled for EfiLoaderData, EfiBootServicesData\n" - "and/or EfiRuntimeServicesData.
" - #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdDxeNxMemoryProtectionPolicy_PROMPT #language en-US "Set DXE memory protection policy." #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdDxeNxMemoryProtectionPolicy_HELP #language en-US "Set DXE memory protection policy. The policy is bitwise.\n" diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c index ef71a3a7e1..812425c53f 100644 --- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c +++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c @@ -314,7 +314,8 @@ ReadyToLockEventNotify ( &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 d1438b8a6a..18bb77236a 100644 --- a/MdePkg/Include/Library/PeCoffLib2.h +++ b/MdePkg/Include/Library/PeCoffLib2.h @@ -22,6 +22,17 @@ #include +typedef enum { + UefiImageOriginFv = 0, + UefiImageOriginOptionROM = 1, + 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? // // PcdImageLoaderAlignmentPolicy bits. @@ -186,7 +197,8 @@ RETURN_STATUS PeCoffInitializeContext ( OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UINT8 ImageOrigin ); /** diff --git a/MdePkg/Include/Library/UefiImageLib.h b/MdePkg/Include/Library/UefiImageLib.h index 957b7f17be..45a4423675 100644 --- a/MdePkg/Include/Library/UefiImageLib.h +++ b/MdePkg/Include/Library/UefiImageLib.h @@ -149,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 @@ -168,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. **/ @@ -177,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 ); /** @@ -671,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/BasePeCoffLib2.inf b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf index 95cfb62beb..57dcf57438 100644 --- a/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf +++ b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf @@ -46,3 +46,4 @@ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c b/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c index 897b168fdd..ccac007595 100644 --- a/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c @@ -339,7 +339,8 @@ STATIC RETURN_STATUS InternalInitializePe ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UINT8 ImageOrigin ) { BOOLEAN Overflow; @@ -356,6 +357,7 @@ InternalInitializePe ( UINT32 NumberOfRvaAndSizes; RETURN_STATUS Status; UINT32 StartAddress; + UINT32 Policy; ASSERT (Context != NULL); ASSERT (sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR) + sizeof (UINT16) <= FileSize - Context->ExeHdrOffset); @@ -479,6 +481,26 @@ 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) { + // + // 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; + } + + return RETURN_NOT_STARTED; + } + } STATIC_ASSERT ( sizeof (EFI_IMAGE_DATA_DIRECTORY) <= MAX_UINT32 / EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES, @@ -649,7 +671,8 @@ RETURN_STATUS PeCoffInitializeContext ( OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -711,7 +734,7 @@ PeCoffInitializeContext ( // // Verify the PE Image Header is well-formed. // - Status = InternalInitializePe (Context, FileSize); + Status = InternalInitializePe (Context, FileSize, ImageOrigin); if (Status != RETURN_SUCCESS) { return Status; } 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 27dff54b7f..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); + return PeCoffInitializeContext (&Context->Ctx.Pe, FileBuffer, FileSize, ImageOrigin); } BOOLEAN @@ -528,7 +529,8 @@ InternalDebugLocateImage ( OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, IN CHAR8 *Buffer, IN UINTN Address, - IN BOOLEAN Recurse + IN BOOLEAN Recurse, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -557,7 +559,8 @@ InternalDebugLocateImage ( Status = PeCoffInitializeContext ( Context, Buffer, - MAX_UINT32 + MAX_UINT32, + ImageOrigin ); if (RETURN_ERROR (Status)) { continue; @@ -576,7 +579,8 @@ InternalDebugLocateImage ( &DosContext, Buffer - 4, Address, - TRUE + TRUE, + ImageOrigin ); if (!RETURN_ERROR (DosStatus)) { Buffer = DosContext.ImageBuffer; @@ -611,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; @@ -641,7 +646,8 @@ UefiImageDebugLocateImagePe ( &Context->Ctx.Pe, (CHAR8 *) (Address & ~(UINTN) 3U), Address, - FALSE + FALSE, + ImageOrigin ); DEBUG_CODE_END (); @@ -710,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 9739e50b29..9596b1102a 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; @@ -156,7 +160,8 @@ UefiImageInitializeContextPreHash ( Context, FileBuffer, FileSize, - UefiImageFormatPe + UefiImageFormatPe, + ImageOrigin ); if (!RETURN_ERROR (Status)) { Context->FormatIndex = UefiImageFormatPe; @@ -624,7 +629,8 @@ UefiImageLoaderGetImageRecord ( RETURN_STATUS UefiImageDebugLocateImage ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINTN Address + IN UINTN Address, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -634,7 +640,8 @@ UefiImageDebugLocateImage ( Context->FormatIndex, DebugLocateImage, Context, - Address + Address, + ImageOrigin ); return Status; diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 9b686113f9..84f416b466 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -2330,6 +2330,27 @@ # @Prompt Supported UEFI image file formats inside FVs. gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x01|UINT8|0x40002001 + ## Set image protection policy. The policy is applied for each source individually. + # If a bit is set, aligned images from this source will be protected and + # unaligned images won't be loaded. Image protection means that + # the code section becomes read-only, and the data section becomes non-executable.
+ # If a bit is cleared, both aligned and unaligned images from this source will + # be loaded but protection will be applied only to aligned images.
+ # Image is aligned, if its SectionAlignment is a power of 2 and >= 4KB.
+ # If BIT31 is set, unaligned image from firmware volume will stop boot process.
+ # If BIT31 is cleared, unaligned images from firmware volume will be ignored.
+ # + # BIT0 - Images from firmware volume.
+ # BIT1 - Images from option ROM.
+ # 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 + [PcdsFixedAtBuild,PcdsPatchableInModule] ## Indicates the maximum length of unicode string used in the following # BaseLib functions: StrLen(), StrSize(), StrCmp(), StrnCmp(), StrCpy(), StrnCpy()

diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc index 222d55fba3..240d07e7e1 100644 --- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc +++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc @@ -480,6 +480,7 @@ # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF40 gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 !else # Allow execution of EfiConventionalMemory and EfiBootServicesData memory regions. gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF45 diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf index 585d504637..49025f3063 100644 --- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf +++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf @@ -78,7 +78,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index c2afa6c116..b180522478 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -587,10 +587,11 @@ # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF40 gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 !elseif $(WINDOWS_10_IA32) == TRUE # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiRuntimeServicesData memory regions. gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF04 - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x0 + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x70000000 !endif # diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index b8e895d04f..b38b67ed83 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -562,7 +562,6 @@ gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi|FALSE gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask|0x1 - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 # # Firmware volume supports UE, and may require PE. @@ -607,10 +606,7 @@ # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF40 gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE - !elseif $(WINDOWS_10_IA32) == TRUE - # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiRuntimeServicesData memory regions. - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF04 - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x0 + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 !endif ################################################################################ diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 62c227b792..147dbc4087 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -617,6 +617,7 @@ # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF40 gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 !endif # diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc index b8338d2eb5..dcce4f947f 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc +++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc @@ -272,12 +272,6 @@ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20 gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0 - # - # Enable strict image permissions for all images. (This applies - # only to images that were built with >= 4 KB section alignment.) - # - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x3 - # # Enable NX memory protection for all non-code regions, including OEM and OS # reserved ones, with the exception of LoaderData regions, of which OS loaders diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c index 17662559b8..437b81c99b 100644 --- a/OvmfPkg/Sec/SecMain.c +++ b/OvmfPkg/Sec/SecMain.c @@ -726,7 +726,8 @@ FindAndReportEntryPoints ( &ImageContext, (VOID *) (UINTN) SecCoreImageBase, SecCoreImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); @@ -742,7 +743,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 a5d1686fc2..2b73c07880 100644 --- a/UefiCpuPkg/SecCore/FindPeiCore.c +++ b/UefiCpuPkg/SecCore/FindPeiCore.c @@ -173,7 +173,8 @@ FindAndReportEntryPoints ( &ImageContext, (VOID*) (UINTN) SecCoreImageBase, SecCoreImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); @@ -200,7 +201,8 @@ FindAndReportEntryPoints ( &ImageContext, (VOID*)(UINTN)PeiCoreImageBase, PeiCoreImageSize, - 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 1f6abec34b..0a54e5d5de 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c +++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c @@ -40,7 +40,8 @@ LoadUefiImage ( &ImageContext, UefiImage, UefiImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf index b0d9eb1b5d..128f8c4979 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf @@ -94,4 +94,4 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf index 485efbb636..b8e8f4b5a0 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf @@ -93,4 +93,4 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES