summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJian J Wang <jian.j.wang@intel.com>2017-12-07 20:17:49 +0800
committerStar Zeng <star.zeng@intel.com>2017-12-08 14:38:52 +0800
commit50255363cbf0555e0f09adfb327189bd7a4be9da (patch)
tree637c90684f51821b0707fb557b26fb202855d201
parenta8ab14d355072241915d87de86770c0fde92cba9 (diff)
downloadedk2-50255363cbf0555e0f09adfb327189bd7a4be9da.zip
edk2-50255363cbf0555e0f09adfb327189bd7a4be9da.tar.gz
edk2-50255363cbf0555e0f09adfb327189bd7a4be9da.tar.bz2
MdeModulePkg/DxeIpl: Enable paging for Stack Guard
Stack guard feature makes use of paging mechanism to monitor if there's a stack overflow occurred during boot. This patch will check setting of PCD PcdCpuStackGuard. If it's TRUE, DxeIpl will setup page table and set the page at which the stack base locates to be NOT PRESENT. If stack is used up and memory access cross into the last page of it, #PF exception will be triggered. Cc: Star Zeng <star.zeng@intel.com> Cc: Eric Dong <eric.dong@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Suggested-by: Ayellet Wolman <ayellet.wolman@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang <jian.j.wang@intel.com> Reviewed-by: Jeff Fan <vanjeff_919@hotmail.com> Reviewed-by: Jiewen.yao@intel.com
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf5
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c4
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c1
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c51
4 files changed, 46 insertions, 15 deletions
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
index a1b8748..ba1d9c6 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
@@ -49,7 +49,7 @@
[Sources.X64]
X64/VirtualMemory.h
X64/VirtualMemory.c
- X64/DxeLoadFunc.c
+ X64/DxeLoadFunc.c
[Sources.IPF]
Ipf/DxeLoadFunc.c
@@ -117,6 +117,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
[Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES
@@ -132,7 +133,7 @@
#
# [Hob]
# MEMORY_ALLOCATION ## SOMETIMES_PRODUCES # MEMORY_ALLOCATION_MODULE for DxeCore
-# MEMORY_ALLOCATION ## SOMETIMES_PRODUCES # New Stack HoB
+# MEMORY_ALLOCATION ## SOMETIMES_PRODUCES # New Stack HoB
# MEMORY_ALLOCATION ## SOMETIMES_PRODUCES # Old Stack HOB
#
# [Hob.IPF]
diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
index 5649265..441096a 100644
--- a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
@@ -235,6 +235,10 @@ ToBuildPageTable (
return TRUE;
}
+ if (PcdGetBool (PcdCpuStackGuard)) {
+ return TRUE;
+ }
+
if (PcdGetBool (PcdSetNxForStack) && IsExecuteDisableBitAvailable ()) {
return TRUE;
}
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
index f613221..b75a448 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
@@ -95,6 +95,7 @@ HandOffToDxeCore (
// for the DxeIpl and the DxeCore are both X64.
//
ASSERT (PcdGetBool (PcdSetNxForStack) == FALSE);
+ ASSERT (PcdGetBool (PcdCpuStackGuard) == FALSE);
}
//
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
index 29b6205..7f63144 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
@@ -118,6 +118,39 @@ EnableExecuteDisableBit (
}
/**
+ The function will check if page table entry should be splitted to smaller
+ granularity.
+
+ @retval TRUE Page table should be split.
+ @retval FALSE Page table should not be split.
+**/
+BOOLEAN
+ToSplitPageTable (
+ IN EFI_PHYSICAL_ADDRESS Address,
+ IN UINTN Size,
+ IN EFI_PHYSICAL_ADDRESS StackBase,
+ IN UINTN StackSize
+ )
+{
+ if (IsNullDetectionEnabled () && Address == 0) {
+ return TRUE;
+ }
+
+ if (PcdGetBool (PcdCpuStackGuard)) {
+ if (StackBase >= Address && StackBase < (Address + Size)) {
+ return TRUE;
+ }
+ }
+
+ if (PcdGetBool (PcdSetNxForStack)) {
+ if ((Address < StackBase + StackSize) && ((Address + Size) > StackBase)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+/**
Split 2M page to 4K.
@param[in] PhysicalAddress Start physical address the 2M page covered.
@@ -160,7 +193,8 @@ Split2MPageTo4K (
PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K | AddressEncMask;
PageTableEntry->Bits.ReadWrite = 1;
- if (IsNullDetectionEnabled () && PhysicalAddress4K == 0) {
+ if ((IsNullDetectionEnabled () && PhysicalAddress4K == 0) ||
+ (PcdGetBool (PcdCpuStackGuard) && PhysicalAddress4K == StackBase)) {
PageTableEntry->Bits.Present = 0;
} else {
PageTableEntry->Bits.Present = 1;
@@ -214,10 +248,7 @@ Split1GPageTo2M (
PhysicalAddress2M = PhysicalAddress;
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) {
- if ((IsNullDetectionEnabled () && PhysicalAddress2M == 0)
- || (PcdGetBool (PcdSetNxForStack)
- && (PhysicalAddress2M < StackBase + StackSize)
- && ((PhysicalAddress2M + SIZE_2MB) > StackBase))) {
+ if (ToSplitPageTable (PhysicalAddress2M, SIZE_2MB, StackBase, StackSize)) {
//
// Need to split this 2M page that covers NULL or stack range.
//
@@ -359,10 +390,7 @@ CreateIdentityMappingPageTables (
PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry;
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {
- if ((IsNullDetectionEnabled () && PageAddress == 0)
- || (PcdGetBool (PcdSetNxForStack)
- && (PageAddress < StackBase + StackSize)
- && ((PageAddress + SIZE_1GB) > StackBase))) {
+ if (ToSplitPageTable (PageAddress, SIZE_1GB, StackBase, StackSize)) {
Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, StackBase, StackSize);
} else {
//
@@ -391,10 +419,7 @@ CreateIdentityMappingPageTables (
PageDirectoryPointerEntry->Bits.Present = 1;
for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {
- if ((IsNullDetectionEnabled () && PageAddress == 0)
- || (PcdGetBool (PcdSetNxForStack)
- && (PageAddress < StackBase + StackSize)
- && ((PageAddress + SIZE_2MB) > StackBase))) {
+ if (ToSplitPageTable (PageAddress, SIZE_2MB, StackBase, StackSize)) {
//
// Need to split this 2M page that covers NULL or stack range.
//