+\r
+/**\r
+ Remove exec permissions from all regions whose type is identified by\r
+ PcdDxeNxMemoryProtectionPolicy.\r
+**/\r
+STATIC\r
+VOID\r
+InitializeDxeNxMemoryProtectionPolicy (\r
+ VOID\r
+ )\r
+{\r
+ UINTN MemoryMapSize;\r
+ UINTN MapKey;\r
+ UINTN DescriptorSize;\r
+ UINT32 DescriptorVersion;\r
+ EFI_MEMORY_DESCRIPTOR *MemoryMap;\r
+ EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;\r
+ EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;\r
+ EFI_STATUS Status;\r
+ UINT64 Attributes;\r
+ LIST_ENTRY *Link;\r
+ EFI_GCD_MAP_ENTRY *Entry;\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+ EFI_HOB_MEMORY_ALLOCATION *MemoryHob;\r
+ EFI_PHYSICAL_ADDRESS StackBase;\r
+\r
+ //\r
+ // Get the EFI memory map.\r
+ //\r
+ MemoryMapSize = 0;\r
+ MemoryMap = NULL;\r
+\r
+ Status = gBS->GetMemoryMap (\r
+ &MemoryMapSize,\r
+ MemoryMap,\r
+ &MapKey,\r
+ &DescriptorSize,\r
+ &DescriptorVersion\r
+ );\r
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
+ do {\r
+ MemoryMap = (EFI_MEMORY_DESCRIPTOR *) AllocatePool (MemoryMapSize);\r
+ ASSERT (MemoryMap != NULL);\r
+ Status = gBS->GetMemoryMap (\r
+ &MemoryMapSize,\r
+ MemoryMap,\r
+ &MapKey,\r
+ &DescriptorSize,\r
+ &DescriptorVersion\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (MemoryMap);\r
+ }\r
+ } while (Status == EFI_BUFFER_TOO_SMALL);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ StackBase = 0;\r
+ if (PcdGetBool (PcdCpuStackGuard)) {\r
+ //\r
+ // Get the base of stack from Hob.\r
+ //\r
+ Hob.Raw = GetHobList ();\r
+ while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {\r
+ MemoryHob = Hob.MemoryAllocation;\r
+ if (CompareGuid(&gEfiHobMemoryAllocStackGuid, &MemoryHob->AllocDescriptor.Name)) {\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: StackBase = 0x%016lx StackSize = 0x%016lx\n",\r
+ __FUNCTION__,\r
+ MemoryHob->AllocDescriptor.MemoryBaseAddress,\r
+ MemoryHob->AllocDescriptor.MemoryLength\r
+ ));\r
+\r
+ StackBase = MemoryHob->AllocDescriptor.MemoryBaseAddress;\r
+ //\r
+ // Ensure the base of the stack is page-size aligned.\r
+ //\r
+ ASSERT ((StackBase & EFI_PAGE_MASK) == 0);\r
+ break;\r
+ }\r
+ Hob.Raw = GET_NEXT_HOB (Hob);\r
+ }\r
+\r
+ //\r
+ // Ensure the base of stack can be found from Hob when stack guard is\r
+ // enabled.\r
+ //\r
+ ASSERT (StackBase != 0);\r
+ }\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: applying strict permissions to active memory regions\n",\r
+ __FUNCTION__\r
+ ));\r
+\r
+ MergeMemoryMapForProtectionPolicy (MemoryMap, &MemoryMapSize, DescriptorSize);\r
+\r
+ MemoryMapEntry = MemoryMap;\r
+ MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize);\r
+ while ((UINTN) MemoryMapEntry < (UINTN) MemoryMapEnd) {\r
+\r
+ Attributes = GetPermissionAttributeForMemoryType (MemoryMapEntry->Type);\r
+ if (Attributes != 0) {\r
+ SetUefiImageMemoryAttributes (\r
+ MemoryMapEntry->PhysicalStart,\r
+ LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT),\r
+ Attributes);\r
+\r
+ //\r
+ // Add EFI_MEMORY_RP attribute for page 0 if NULL pointer detection is\r
+ // enabled.\r
+ //\r
+ if (MemoryMapEntry->PhysicalStart == 0 &&\r
+ PcdGet8 (PcdNullPointerDetectionPropertyMask) != 0) {\r
+\r
+ ASSERT (MemoryMapEntry->NumberOfPages > 0);\r
+ SetUefiImageMemoryAttributes (\r
+ 0,\r
+ EFI_PAGES_TO_SIZE (1),\r
+ EFI_MEMORY_RP | Attributes);\r
+ }\r
+\r
+ //\r
+ // Add EFI_MEMORY_RP attribute for the first page of the stack if stack\r
+ // guard is enabled.\r
+ //\r
+ if (StackBase != 0 &&\r
+ (StackBase >= MemoryMapEntry->PhysicalStart &&\r
+ StackBase < MemoryMapEntry->PhysicalStart +\r
+ LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT)) &&\r
+ PcdGetBool (PcdCpuStackGuard)) {\r
+\r
+ SetUefiImageMemoryAttributes (\r
+ StackBase,\r
+ EFI_PAGES_TO_SIZE (1),\r
+ EFI_MEMORY_RP | Attributes);\r
+ }\r
+\r
+ }\r
+ MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
+ }\r
+ FreePool (MemoryMap);\r
+\r
+ //\r
+ // Apply the policy for RAM regions that we know are present and\r
+ // accessible, but have not been added to the UEFI memory map (yet).\r
+ //\r
+ if (GetPermissionAttributeForMemoryType (EfiConventionalMemory) != 0) {\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: applying strict permissions to inactive memory regions\n",\r
+ __FUNCTION__\r
+ ));\r
+\r
+ CoreAcquireGcdMemoryLock ();\r
+\r
+ Link = mGcdMemorySpaceMap.ForwardLink;\r
+ while (Link != &mGcdMemorySpaceMap) {\r
+\r
+ Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);\r
+\r
+ if (Entry->GcdMemoryType == EfiGcdMemoryTypeReserved &&\r
+ Entry->EndAddress < MAX_ADDRESS &&\r
+ (Entry->Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==\r
+ (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)) {\r
+\r
+ Attributes = GetPermissionAttributeForMemoryType (EfiConventionalMemory) |\r
+ (Entry->Attributes & CACHE_ATTRIBUTE_MASK);\r
+\r
+ DEBUG ((DEBUG_INFO,\r
+ "Untested GCD memory space region: - 0x%016lx - 0x%016lx (0x%016lx)\n",\r
+ Entry->BaseAddress, Entry->EndAddress - Entry->BaseAddress + 1,\r
+ Attributes));\r
+\r
+ ASSERT(gCpu != NULL);\r
+ gCpu->SetMemoryAttributes (gCpu, Entry->BaseAddress,\r
+ Entry->EndAddress - Entry->BaseAddress + 1, Attributes);\r
+ }\r
+\r
+ Link = Link->ForwardLink;\r
+ }\r
+ CoreReleaseGcdMemoryLock ();\r
+ }\r
+}\r
+\r
+\r