49#define IMAGE_UNKNOWN 0x00000001
50#define IMAGE_FROM_FV 0x00000002
55#define DO_NOT_PROTECT 0x00000000
56#define PROTECT_IF_ALIGNED_ELSE_ALLOW 0x00000001
58#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000
59#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000
61#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
62 ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
64UINT32 mImageProtectionPolicy;
96 Status =
gBS->LocateDevicePath (
97 &gEfiFirmwareVolume2ProtocolGuid,
101 if (!EFI_ERROR (Status)) {
102 Status =
gBS->OpenProtocol (
104 &gEfiFirmwareVolume2ProtocolGuid,
108 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
110 if (!EFI_ERROR (Status)) {
111 return IMAGE_FROM_FV;
115 return IMAGE_UNKNOWN;
130 if ((ImageType & mImageProtectionPolicy) == 0) {
131 return DO_NOT_PROTECT;
133 return PROTECT_IF_ALIGNED_ELSE_ALLOW;
153 UINT32 ProtectionPolicy;
159 if (gSmmBase2 !=
NULL) {
160 gSmmBase2->InSmm (gSmmBase2, &
InSmm);
170 if (LoadedImage == gDxeCoreLoadedImage) {
171 ImageType = IMAGE_FROM_FV;
177 return ProtectionPolicy;
189 IN UINT64 BaseAddress,
196 UINT64 FinalAttributes;
201 FinalAttributes = (Descriptor.
Attributes & EFI_CACHE_ATTRIBUTE_MASK) | (Attributes & EFI_MEMORY_ATTRIBUTE_MASK);
203 DEBUG ((DEBUG_INFO,
"SetUefiImageMemoryAttributes - 0x%016lx - 0x%016lx (0x%016lx)\n", BaseAddress, Length, FinalAttributes));
205 ASSERT (gCpu !=
NULL);
206 gCpu->SetMemoryAttributes (gCpu, BaseAddress, Length, FinalAttributes);
226 ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
228 CurrentBase = ImageRecord->ImageBase;
229 ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize;
231 ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
232 ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;
233 while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {
234 ImageRecordCodeSection =
CR (
235 ImageRecordCodeSectionLink,
238 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
240 ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
242 ASSERT (CurrentBase <= ImageRecordCodeSection->CodeSegmentBase);
243 if (CurrentBase < ImageRecordCodeSection->CodeSegmentBase) {
249 ImageRecordCodeSection->CodeSegmentBase - CurrentBase,
258 ImageRecordCodeSection->CodeSegmentBase,
259 ImageRecordCodeSection->CodeSegmentSize,
262 CurrentBase = ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize;
268 ASSERT (CurrentBase <= ImageEnd);
269 if (CurrentBase < ImageEnd) {
275 ImageEnd - CurrentBase,
297 UINT32 SectionAlignment;
299 switch (MemoryType) {
303 SectionAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
307 SectionAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
311 SectionAlignment = EFI_PAGE_SIZE;
316 SectionAlignment = EFI_PAGE_SIZE;
320 return SectionAlignment;
336 UINT32 ProtectionPolicy;
338 UINT32 RequiredAlignment;
340 DEBUG ((DEBUG_INFO,
"ProtectUefiImageCommon - 0x%x\n", LoadedImage));
348 switch (ProtectionPolicy) {
351 case PROTECT_IF_ALIGNED_ELSE_ALLOW:
359 if (ImageRecord ==
NULL) {
366 LoadedImage->ImageBase,
367 LoadedImage->ImageSize,
372 if (EFI_ERROR (Status)) {
373 DEBUG ((DEBUG_ERROR,
"%a failed to create image properties record\n", __func__));
407 if (
PcdGet32 (PcdImageProtectionPolicy) != 0) {
408 for (ImageRecordLink = mProtectedImageRecordList.ForwardLink;
409 ImageRecordLink != &mProtectedImageRecordList;
410 ImageRecordLink = ImageRecordLink->ForwardLink)
416 IMAGE_PROPERTIES_RECORD_SIGNATURE
421 ImageRecord->ImageBase,
422 ImageRecord->ImageSize,
446 if ((UINT32)MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) {
448 }
else if ((UINT32)MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) {
454 if ((
PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & TestBit) != 0) {
455 return EFI_MEMORY_XP;
482 MemoryMapEntry = MemoryMap;
483 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
485 while (MemoryMapEntry < MemoryMapEnd) {
486 while (NextMemoryMapEntry < MemoryMapEnd) {
493 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
496 MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
497 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
522 UINT64 MemoryBlockLength;
529 MemoryMapEntry = MemoryMap;
530 NewMemoryMapEntry = MemoryMap;
532 while ((
UINTN)MemoryMapEntry < (
UINTN)MemoryMapEnd) {
534 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
540 if (((
UINTN)NextMemoryMapEntry < (
UINTN)MemoryMapEnd) &&
545 if (NewMemoryMapEntry != MemoryMapEntry) {
549 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
552 MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
557 MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
558 NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize);
561 *MemoryMapSize = (
UINTN)NewMemoryMapEntry - (
UINTN)MemoryMap;
578 UINTN DescriptorSize;
579 UINT32 DescriptorVersion;
597 Status =
gBS->GetMemoryMap (
604 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
607 ASSERT (MemoryMap !=
NULL);
608 Status =
gBS->GetMemoryMap (
615 if (EFI_ERROR (Status)) {
618 }
while (Status == EFI_BUFFER_TOO_SMALL);
628 while ((Hob.Raw =
GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) !=
NULL) {
629 MemoryHob = Hob.MemoryAllocation;
633 "%a: StackBase = 0x%016lx StackSize = 0x%016lx\n",
643 ASSERT ((StackBase & EFI_PAGE_MASK) == 0);
647 Hob.Raw = GET_NEXT_HOB (Hob);
654 ASSERT (StackBase != 0);
659 "%a: applying strict permissions to active memory regions\n",
665 MemoryMapEntry = MemoryMap;
667 while ((
UINTN)MemoryMapEntry < (
UINTN)MemoryMapEnd) {
669 if (Attributes != 0) {
681 (
PcdGet8 (PcdNullPointerDetectionPropertyMask) != 0))
687 EFI_MEMORY_RP | Attributes
695 if ((StackBase != 0) &&
697 (StackBase < MemoryMapEntry->PhysicalStart +
704 EFI_MEMORY_RP | Attributes
709 MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
721 "%a: applying strict permissions to inactive memory regions\n",
727 Link = mGcdMemorySpaceMap.ForwardLink;
728 while (Link != &mGcdMemorySpaceMap) {
733 ((Entry->Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
734 (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)))
737 (Entry->Attributes & EFI_CACHE_ATTRIBUTE_MASK);
741 "Untested GCD memory space region: - 0x%016lx - 0x%016lx (0x%016lx)\n",
743 Entry->EndAddress - Entry->BaseAddress + 1,
747 ASSERT (gCpu !=
NULL);
748 gCpu->SetMemoryAttributes (
751 Entry->EndAddress - Entry->BaseAddress + 1,
756 Link = Link->ForwardLink;
785 DEBUG ((DEBUG_INFO,
"MemoryProtectionCpuArchProtocolNotify:\n"));
787 if (EFI_ERROR (Status)) {
794 if (
PcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0) {
803 if (mImageProtectionPolicy == 0) {
807 Status =
gBS->LocateHandleBuffer (
809 &gEfiLoadedImageProtocolGuid,
814 if (EFI_ERROR (Status) && (NoHandles == 0)) {
818 for (Index = 0; Index < NoHandles; Index++) {
819 Status =
gBS->HandleProtocol (
821 &gEfiLoadedImageProtocolGuid,
822 (VOID **)&LoadedImage
824 if (EFI_ERROR (Status)) {
828 Status =
gBS->HandleProtocol (
830 &gEfiLoadedImageDevicePathProtocolGuid,
831 (VOID **)&LoadedImageDevicePath
833 if (EFI_ERROR (Status)) {
834 LoadedImageDevicePath =
NULL;
866 if (mImageProtectionPolicy != 0) {
867 for (Link = gRuntime->
ImageHead.ForwardLink; Link != &gRuntime->
ImageHead; Link = Link->ForwardLink) {
892 DEBUG ((DEBUG_INFO,
"DisableNullDetectionAtTheEndOfDxe(): start\r\n"));
899 if ((Desc.Capabilities & EFI_MEMORY_RP) == 0) {
903 Desc.Capabilities | EFI_MEMORY_RP
911 Desc.Attributes & ~EFI_MEMORY_RP
921 DEBUG ((DEBUG_INFO,
"DisableNullDetectionAtTheEndOfDxe(): end\r\n"));
940 mImageProtectionPolicy =
PcdGet32 (PcdImageProtectionPolicy);
971 &gEfiCpuArchProtocolGuid,
980 if ((
PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7))
988 &gEfiEndOfDxeEventGroupGuid,
1009 if (gSmmBase2 !=
NULL) {
1010 gSmmBase2->InSmm (gSmmBase2, &
InSmm);
1042 UINT64 OldAttributes;
1043 UINT64 NewAttributes;
1065 if (
PcdGet64 (PcdDxeNxMemoryProtectionPolicy) == 0) {
1075 Memory += EFI_PAGE_SIZE;
1076 Length -= EFI_PAGE_SIZE;
1082 if (
IsGuardPage (Memory + Length - EFI_PAGE_SIZE)) {
1083 Length -= EFI_PAGE_SIZE;
1098 if (OldType != EfiMaxMemoryType) {
1100 if (OldAttributes == NewAttributes) {
1104 }
else if (NewAttributes == 0) {
1109 return gCpu->SetMemoryAttributes (gCpu, Memory, Length, NewAttributes);
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
VOID *EFIAPI GetHobList(VOID)
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
BOOLEAN EFIAPI IsGuardPage(IN EFI_PHYSICAL_ADDRESS Address)
BOOLEAN IsHeapGuardEnabled(UINT8 GuardType)
VOID HeapGuardCpuArchProtocolNotify(VOID)
EFI_STATUS EFIAPI CoreFreePages(IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages)
EFI_STATUS EFIAPI CoreGetMemorySpaceDescriptor(IN EFI_PHYSICAL_ADDRESS BaseAddress, OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor)
EFI_STATUS EFIAPI CoreLocateProtocol(IN EFI_GUID *Protocol, IN VOID *Registration OPTIONAL, OUT VOID **Interface)
VOID CoreAcquireGcdMemoryLock(VOID)
EFI_STATUS EFIAPI CoreSetMemorySpaceCapabilities(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Capabilities)
EFI_STATUS EFIAPI CoreSetMemorySpaceAttributes(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
EFI_STATUS EFIAPI CoreRegisterProtocolNotify(IN EFI_GUID *Protocol, IN EFI_EVENT Event, OUT VOID **Registration)
EFI_STATUS EFIAPI CoreCreateEventEx(IN UINT32 Type, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, IN CONST VOID *NotifyContext OPTIONAL, IN CONST EFI_GUID *EventGroup OPTIONAL, OUT EFI_EVENT *Event)
EFI_STATUS EFIAPI CoreCloseEvent(IN EFI_EVENT UserEvent)
VOID CoreReleaseGcdMemoryLock(VOID)
EFI_STATUS EFIAPI CoreCreateEvent(IN UINT32 Type, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, IN VOID *NotifyContext OPTIONAL, OUT EFI_EVENT *Event)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID EFIAPI DeleteImagePropertiesRecord(IN IMAGE_PROPERTIES_RECORD *ImageRecord)
EFI_STATUS EFIAPI CreateImagePropertiesRecord(IN CONST VOID *ImageBase, IN CONST UINT64 ImageSize, IN CONST UINT32 *Alignment OPTIONAL, OUT IMAGE_PROPERTIES_RECORD *ImageRecord)
#define ALIGN_VALUE(Value, Alignment)
#define BASE_CR(Record, TYPE, Field)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define CR(Record, TYPE, Field, TestSignature)
UINT32 GetUefiImageProtectionPolicy(IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath)
STATIC BOOLEAN IsInSmm(VOID)
VOID MemoryProtectionExitBootServicesCallback(VOID)
VOID SetUefiImageMemoryAttributes(IN UINT64 BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
VOID ProtectUefiImage(IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath)
UINT32 GetImageType(IN CONST EFI_DEVICE_PATH_PROTOCOL *File)
STATIC VOID MergeMemoryMapForProtectionPolicy(IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, IN OUT UINTN *MemoryMapSize, IN UINTN DescriptorSize)
VOID SetUefiImageProtectionAttributes(IN IMAGE_PROPERTIES_RECORD *ImageRecord)
STATIC VOID InitializeDxeNxMemoryProtectionPolicy(VOID)
VOID EFIAPI DisableNullDetectionAtTheEndOfDxe(EFI_EVENT Event, VOID *Context)
UINT32 GetProtectionPolicyFromImageType(IN UINT32 ImageType)
EFI_STATUS EFIAPI ApplyMemoryProtectionPolicy(IN EFI_MEMORY_TYPE OldType, IN EFI_MEMORY_TYPE NewType, IN EFI_PHYSICAL_ADDRESS Memory, IN UINT64 Length)
STATIC UINT32 GetMemoryProtectionSectionAlignment(IN EFI_MEMORY_TYPE MemoryType)
VOID EFIAPI CoreInitializeMemoryProtection(VOID)
STATIC VOID SortMemoryMap(IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, IN UINTN MemoryMapSize, IN UINTN DescriptorSize)
VOID EFIAPI MemoryProtectionCpuArchProtocolNotify(IN EFI_EVENT Event, IN VOID *Context)
VOID UnprotectUefiImage(IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath)
STATIC UINT64 GetPermissionAttributeForMemoryType(IN EFI_MEMORY_TYPE MemoryType)
#define PcdGet64(TokenName)
#define PcdGet8(TokenName)
#define PcdGet32(TokenName)
#define PcdGetBool(TokenName)
@ EfiGcdMemoryTypeReserved
BOOLEAN EFIAPI InSmm(VOID)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_PAGES_TO_SIZE(Pages)
EFI_LIST_ENTRY ImageHead
A list of type EFI_RUNTIME_IMAGE_ENTRY.
EFI_PHYSICAL_ADDRESS MemoryBaseAddress
EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor
EFI_PHYSICAL_ADDRESS PhysicalStart