\r
Once the image is unloaded, the protection is removed automatically.\r
\r
-Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
#include <Guid/PropertiesTable.h>\r
\r
#include <Protocol/FirmwareVolume2.h>\r
-#include <Protocol/BlockIo.h>\r
#include <Protocol/SimpleFileSystem.h>\r
\r
#include "DxeMain.h"\r
+#include "Mem/HeapGuard.h"\r
\r
#define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP)\r
#define MEMORY_ATTRIBUTE_MASK (EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RO)\r
IMAGE_PROPERTIES_RECORD *ImageRecord;\r
CHAR8 *PdbPointer;\r
IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;\r
- UINT16 Magic;\r
BOOLEAN IsAligned;\r
UINT32 ProtectionPolicy;\r
\r
//\r
// Get SectionAlignment\r
//\r
- if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- //\r
- // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value\r
- // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the\r
- // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC\r
- // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
- //\r
- Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
- } else {\r
- //\r
- // Get the magic value from the PE/COFF Optional Header\r
- //\r
- Magic = Hdr.Pe32->OptionalHeader.Magic;\r
- }\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment;\r
} else {\r
SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment;\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
} 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
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
DEBUG ((DEBUG_INFO, "MemoryProtectionCpuArchProtocolNotify:\n"));\r
Status = CoreLocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);\r
if (EFI_ERROR (Status)) {\r
- return;\r
+ goto Done;\r
}\r
\r
//\r
InitializeDxeNxMemoryProtectionPolicy ();\r
}\r
\r
+ //\r
+ // Call notify function meant for Heap Guard.\r
+ //\r
+ HeapGuardCpuArchProtocolNotify ();\r
+\r
if (mImageProtectionPolicy == 0) {\r
- return;\r
+ goto Done;\r
}\r
\r
Status = gBS->LocateHandleBuffer (\r
&HandleBuffer\r
);\r
if (EFI_ERROR (Status) && (NoHandles == 0)) {\r
- return ;\r
+ goto Done;\r
}\r
\r
for (Index = 0; Index < NoHandles; Index++) {\r
\r
ProtectUefiImage (LoadedImage, LoadedImageDevicePath);\r
}\r
+ FreePool (HandleBuffer);\r
\r
+Done:\r
CoreCloseEvent (Event);\r
- return;\r
}\r
\r
/**\r
return EFI_SUCCESS;\r
}\r
\r
+ //\r
+ // Don't overwrite Guard pages, which should be the first and/or last page,\r
+ // if any.\r
+ //\r
+ if (IsHeapGuardEnabled (GUARD_HEAP_TYPE_PAGE|GUARD_HEAP_TYPE_POOL)) {\r
+ if (IsGuardPage (Memory)) {\r
+ Memory += EFI_PAGE_SIZE;\r
+ Length -= EFI_PAGE_SIZE;\r
+ if (Length == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ if (IsGuardPage (Memory + Length - EFI_PAGE_SIZE)) {\r
+ Length -= EFI_PAGE_SIZE;\r
+ if (Length == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ }\r
+\r
//\r
// Update the executable permissions according to the DXE memory\r
// protection policy, but only if\r