From: Jian J Wang <jian.j.wang@intel.com>
To: edk2-devel@lists.01.org
Cc: Star Zeng <star.zeng@intel.com>, Eric Dong <eric.dong@intel.com>
Subject: [PATCH 2/3] MdeModulePkg/DxeIpl: Enable paging for stack guard
Date: Tue, 31 Oct 2017 22:24:11 +0800 [thread overview]
Message-ID: <20171031142412.21680-3-jian.j.wang@intel.com> (raw)
In-Reply-To: <20171031142412.21680-1-jian.j.wang@intel.com>
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>
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>
---
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 1 +
MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 35 ++++++++++++++--
MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c | 1 +
MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c | 51 ++++++++++++++++++------
4 files changed, 71 insertions(+), 17 deletions(-)
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
index 9d0e76a293..bc857629f8 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
@@ -116,6 +116,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES
[Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64]
gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES
diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
index 96f5718444..92f2247bd4 100644
--- a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
@@ -211,6 +211,36 @@ IsExecuteDisableBitAvailable (
return Available;
}
+/**
+ The function will check if page table should be setup or not.
+
+ @retval TRUE Page table should be created.
+ @retval FALSE Page table should not be created.
+**/
+BOOLEAN
+ToBuildPageTable (
+ VOID
+ )
+{
+ if (!IsIa32PaeSupport ()) {
+ return FALSE;
+ }
+
+ if (IsNullDetectionEnabled ()) {
+ return TRUE;
+ }
+
+ if (PcdGetBool (PcdCpuStackGuard)) {
+ return TRUE;
+ }
+
+ if (PcdGetBool (PcdSetNxForStack) && IsExecuteDisableBitAvailable ()) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/**
Transfers control to DxeCore.
@@ -385,10 +415,7 @@ HandOffToDxeCore (
TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
PageTables = 0;
- BuildPageTablesIa32Pae = (BOOLEAN) (IsIa32PaeSupport () &&
- (IsNullDetectionEnabled () ||
- (PcdGetBool (PcdSetNxForStack) &&
- IsExecuteDisableBitAvailable ())));
+ BuildPageTablesIa32Pae = ToBuildPageTable();
if (BuildPageTablesIa32Pae) {
PageTables = Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE);
if (IsExecuteDisableBitAvailable ()) {
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
index f613221b81..b75a4489bf 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 29b6205e88..a2466b7766 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
@@ -117,6 +117,39 @@ EnableExecuteDisableBit (
AsmWriteMsr64 (0xC0000080, MsrRegisters);
}
+/**
+ The function will check if page table entry should be splitted to smaller
+ granularity.
+
+ @retval TRUE Page table should be created.
+ @retval FALSE Page table should not be created.
+**/
+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.
@@ -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.
//
--
2.14.1.windows.1
next prev parent reply other threads:[~2017-10-31 14:22 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-31 14:24 [PATCH 0/3] Implement stack guard feature Jian J Wang
2017-10-31 14:24 ` [PATCH 1/3] MdeModulePkg/metafile: Add PCD PcdCpuStackGuard Jian J Wang
2017-10-31 14:24 ` Jian J Wang [this message]
2017-10-31 14:24 ` [PATCH 3/3] UefiCpuPkg/CpuExceptionHandlerLib: Add stack switch support Jian J Wang
2017-11-01 1:56 ` Yao, Jiewen
2017-11-01 2:33 ` 答复: " Fan Jeff
2017-11-01 2:48 ` Wang, Jian J
2017-11-01 2:59 ` 答复: " Fan Jeff
2017-11-01 3:08 ` Wang, Jian J
2017-11-01 3:12 ` Wang, Jian J
2017-11-01 3:45 ` 答复: " Fan Jeff
2017-11-01 3:12 ` Fan Jeff
2017-11-01 15:42 ` Kinney, Michael D
2017-11-03 1:24 ` Yao, Jiewen
2017-11-03 2:10 ` Wang, Jian J
2017-11-03 2:27 ` Yao, Jiewen
2017-11-03 2:30 ` Wang, Jian J
2017-11-03 8:21 ` 答复: " Fan Jeff
2017-11-03 8:58 ` Fan Jeff
2017-11-06 0:30 ` Wang, Jian J
2017-11-06 1:54 ` Yao, Jiewen
2017-11-06 2:27 ` Wang, Jian J
2017-11-06 3:47 ` Yao, Jiewen
2017-11-06 3:10 ` 答复: " Fan Jeff
2017-11-06 2:00 ` Fan Jeff
2017-11-01 2:36 ` Wang, Jian J
2017-11-01 2:37 ` 答复: " Fan Jeff
2017-11-01 2:45 ` Wang, Jian J
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171031142412.21680-3-jian.j.wang@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox