SecurePE: Defined new PcdImageProtectionPolicy.

This commit is contained in:
Mikhail Krichanov 2024-07-01 12:24:47 +03:00
parent 7a25dcfffb
commit 46050fc0fc
47 changed files with 225 additions and 199 deletions

View File

@ -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);

View File

@ -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

View File

@ -156,7 +156,8 @@ RelocateUefiImage (
&ImageContext,
SectionData,
SectionSize,
UEFI_IMAGE_SOURCE_FV
UEFI_IMAGE_SOURCE_FV,
UefiImageOriginFv
);
ASSERT_RETURN_ERROR (Status);

View File

@ -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 ();

View File

@ -209,7 +209,8 @@ ToolContextConstructUefiImage (
&Context,
File,
(UINT32)FileSize,
UEFI_IMAGE_SOURCE_FV
UEFI_IMAGE_SOURCE_FV,
UefiImageOriginFv
);
if (RETURN_ERROR (Status)) {
return Status;

View File

@ -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);

View File

@ -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);

View File

@ -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);
//

View File

@ -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
}

View File

@ -44,7 +44,8 @@ LoadUefiImage (
&ImageContext,
UefiImage,
UefiImageSize,
UEFI_IMAGE_SOURCE_FV
UEFI_IMAGE_SOURCE_FV,
UefiImageOriginFv
);
ASSERT_EFI_ERROR (Status);

View File

@ -214,7 +214,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables|FALSE
[PcdsFixedAtBuild]
gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000000
gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000000
gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000040
gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x0f

View File

@ -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);

View File

@ -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
);

View File

@ -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

View File

@ -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
//

View File

@ -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,

View File

@ -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));

View File

@ -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

View File

@ -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);

View File

@ -1121,7 +1121,8 @@ ConvertPeiCorePpiPointers (
&ImageContext,
(VOID *) (UINTN) PeiCoreImageBase,
PeiCoreImageSize,
UEFI_IMAGE_SOURCE_FV
UEFI_IMAGE_SOURCE_FV,
UefiImageOriginFv
);
ASSERT_EFI_ERROR (Status);

View File

@ -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) {

View File

@ -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;

View File

@ -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.<BR><BR>
# BIT0 - Image from unknown device. <BR>
# BIT1 - Image from firmware volume.<BR>
# <BR>
# Note: If a bit is cleared, the data section could be still non-executable if
# PcdDxeNxMemoryProtectionPolicy is enabled for EfiLoaderData, EfiBootServicesData
# and/or EfiRuntimeServicesData.<BR>
# <BR>
# @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.<BR>

View File

@ -1098,18 +1098,6 @@
#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdSmiHandlerProfilePropertyMask_HELP #language en-US "The mask is used to control SmiHandlerProfile behavior.<BR><BR>\n"
"BIT0 - Enable SmiHandlerProfile.<BR>"
#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.<BR><BR>\n"
"BIT0 - Image from unknown device. <BR>\n"
"BIT1 - Image from firmware volume.<BR>"
"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.<BR>"
#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"

View File

@ -314,7 +314,8 @@ ReadyToLockEventNotify (
&ImageContext,
Buffer,
(UINT32) BufferSize,
UEFI_IMAGE_SOURCE_FV
UEFI_IMAGE_SOURCE_FV,
UefiImageOriginFv
);
ASSERT_EFI_ERROR (Status);

View File

@ -22,6 +22,17 @@
#include <Guid/WinCertificate.h>
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
);
/**

View File

@ -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
);
/**

View File

@ -46,3 +46,4 @@
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset
gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX
gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy

View File

@ -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;
}

View File

@ -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;

View File

@ -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"

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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.<BR>
# 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.<BR>
# Image is aligned, if its SectionAlignment is a power of 2 and >= 4KB.<BR>
# If BIT31 is set, unaligned image from firmware volume will stop boot process.<BR>
# If BIT31 is cleared, unaligned images from firmware volume will be ignored.<BR>
#
# BIT0 - Images from firmware volume.<BR>
# BIT1 - Images from option ROM.<BR>
# BIT2 - Images supplied by user.<BR>
# <BR>
# BIT31 - Firmware volume policy.<BR>
# BIT30 - Turn off protection for images from firmware volume.<BR>
# BIT29 - Turn off protection for images from option ROM.<BR>
# BIT28 - Turn off protection for images supplied by user.<BR>
# @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()<BR><BR>

View File

@ -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

View File

@ -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

View File

@ -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
#

View File

@ -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
################################################################################

View File

@ -617,6 +617,7 @@
# Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions.
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF40
gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE
gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003
!endif
#

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -94,4 +94,4 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES
gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES

View File

@ -93,4 +93,4 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES
gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES