]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/DxeIpl: Enable paging for Stack Guard
authorJian J Wang <jian.j.wang@intel.com>
Thu, 7 Dec 2017 12:17:49 +0000 (20:17 +0800)
committerStar Zeng <star.zeng@intel.com>
Fri, 8 Dec 2017 06:38:52 +0000 (14:38 +0800)
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
MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c

index a1b8748432d574171d6cb29702560d12f90cbd0b..ba1d9c6b05b3008dd34f645930fff489bf2311e3 100644 (file)
@@ -49,7 +49,7 @@
 [Sources.X64]\r
   X64/VirtualMemory.h\r
   X64/VirtualMemory.c\r
 [Sources.X64]\r
   X64/VirtualMemory.h\r
   X64/VirtualMemory.c\r
-  X64/DxeLoadFunc.c    \r
+  X64/DxeLoadFunc.c\r
 \r
 [Sources.IPF]\r
   Ipf/DxeLoadFunc.c\r
 \r
 [Sources.IPF]\r
   Ipf/DxeLoadFunc.c\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask    ## CONSUMES\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask    ## CONSUMES\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask    ## CONSUMES\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask               ## CONSUMES\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard                       ## CONSUMES\r
 \r
 [Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack               ## SOMETIMES_CONSUMES\r
 \r
 [Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack               ## SOMETIMES_CONSUMES\r
 #\r
 # [Hob]\r
 # MEMORY_ALLOCATION                 ## SOMETIMES_PRODUCES # MEMORY_ALLOCATION_MODULE for DxeCore\r
 #\r
 # [Hob]\r
 # MEMORY_ALLOCATION                 ## SOMETIMES_PRODUCES # MEMORY_ALLOCATION_MODULE for DxeCore\r
-# MEMORY_ALLOCATION                 ## SOMETIMES_PRODUCES # New Stack HoB   \r
+# MEMORY_ALLOCATION                 ## SOMETIMES_PRODUCES # New Stack HoB\r
 # MEMORY_ALLOCATION                 ## SOMETIMES_PRODUCES # Old Stack HOB\r
 #\r
 # [Hob.IPF]\r
 # MEMORY_ALLOCATION                 ## SOMETIMES_PRODUCES # Old Stack HOB\r
 #\r
 # [Hob.IPF]\r
index 56492653671ea4ecc9e05c64107823a61a2a14eb..441096ad0f5e24a5f61a52010ac1d8e1a0a5aef6 100644 (file)
@@ -235,6 +235,10 @@ ToBuildPageTable (
     return TRUE;\r
   }\r
 \r
     return TRUE;\r
   }\r
 \r
+  if (PcdGetBool (PcdCpuStackGuard)) {\r
+    return TRUE;\r
+  }\r
+\r
   if (PcdGetBool (PcdSetNxForStack) && IsExecuteDisableBitAvailable ()) {\r
     return TRUE;\r
   }\r
   if (PcdGetBool (PcdSetNxForStack) && IsExecuteDisableBitAvailable ()) {\r
     return TRUE;\r
   }\r
index f613221b81dd04cbecc11bc658a68ebb0aa25619..b75a4489bf841e3bf5fbb43c915050fe4020f25b 100644 (file)
@@ -95,6 +95,7 @@ HandOffToDxeCore (
     // for the DxeIpl and the DxeCore are both X64.\r
     //\r
     ASSERT (PcdGetBool (PcdSetNxForStack) == FALSE);\r
     // for the DxeIpl and the DxeCore are both X64.\r
     //\r
     ASSERT (PcdGetBool (PcdSetNxForStack) == FALSE);\r
+    ASSERT (PcdGetBool (PcdCpuStackGuard) == FALSE);\r
   }\r
   \r
   //\r
   }\r
   \r
   //\r
index 29b6205e884d8a58aa583ba3d89c965ecd731284..7f6314451028cc763613f132857f754cbc9c7b92 100644 (file)
@@ -117,6 +117,39 @@ EnableExecuteDisableBit (
   AsmWriteMsr64 (0xC0000080, MsrRegisters);\r
 }\r
 \r
   AsmWriteMsr64 (0xC0000080, MsrRegisters);\r
 }\r
 \r
+/**\r
+  The function will check if page table entry should be splitted to smaller\r
+  granularity.\r
+\r
+  @retval TRUE      Page table should be split.\r
+  @retval FALSE     Page table should not be split.\r
+**/\r
+BOOLEAN\r
+ToSplitPageTable (\r
+  IN EFI_PHYSICAL_ADDRESS               Address,\r
+  IN UINTN                              Size,\r
+  IN EFI_PHYSICAL_ADDRESS               StackBase,\r
+  IN UINTN                              StackSize\r
+  )\r
+{\r
+  if (IsNullDetectionEnabled () && Address == 0) {\r
+    return TRUE;\r
+  }\r
+\r
+  if (PcdGetBool (PcdCpuStackGuard)) {\r
+    if (StackBase >= Address && StackBase < (Address + Size)) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  if (PcdGetBool (PcdSetNxForStack)) {\r
+    if ((Address < StackBase + StackSize) && ((Address + Size) > StackBase)) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
 /**\r
   Split 2M page to 4K.\r
 \r
 /**\r
   Split 2M page to 4K.\r
 \r
@@ -160,7 +193,8 @@ Split2MPageTo4K (
     PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K | AddressEncMask;\r
     PageTableEntry->Bits.ReadWrite = 1;\r
 \r
     PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K | AddressEncMask;\r
     PageTableEntry->Bits.ReadWrite = 1;\r
 \r
-    if (IsNullDetectionEnabled () && PhysicalAddress4K == 0) {\r
+    if ((IsNullDetectionEnabled () && PhysicalAddress4K == 0) ||\r
+        (PcdGetBool (PcdCpuStackGuard) && PhysicalAddress4K == StackBase)) {\r
       PageTableEntry->Bits.Present = 0;\r
     } else {\r
       PageTableEntry->Bits.Present = 1;\r
       PageTableEntry->Bits.Present = 0;\r
     } else {\r
       PageTableEntry->Bits.Present = 1;\r
@@ -214,10 +248,7 @@ Split1GPageTo2M (
 \r
   PhysicalAddress2M = PhysicalAddress;\r
   for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) {\r
 \r
   PhysicalAddress2M = PhysicalAddress;\r
   for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) {\r
-    if ((IsNullDetectionEnabled () && PhysicalAddress2M == 0)\r
-        || (PcdGetBool (PcdSetNxForStack)\r
-            && (PhysicalAddress2M < StackBase + StackSize)\r
-            && ((PhysicalAddress2M + SIZE_2MB) > StackBase))) {\r
+    if (ToSplitPageTable (PhysicalAddress2M, SIZE_2MB, StackBase, StackSize)) {\r
       //\r
       // Need to split this 2M page that covers NULL or stack range.\r
       //\r
       //\r
       // Need to split this 2M page that covers NULL or stack range.\r
       //\r
@@ -359,10 +390,7 @@ CreateIdentityMappingPageTables (
       PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry;\r
     \r
       for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {\r
       PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry;\r
     \r
       for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {\r
-        if ((IsNullDetectionEnabled () && PageAddress == 0)\r
-            || (PcdGetBool (PcdSetNxForStack)\r
-                && (PageAddress < StackBase + StackSize)\r
-                && ((PageAddress + SIZE_1GB) > StackBase))) {\r
+        if (ToSplitPageTable (PageAddress, SIZE_1GB, StackBase, StackSize)) {\r
           Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, StackBase, StackSize);\r
         } else {\r
           //\r
           Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, StackBase, StackSize);\r
         } else {\r
           //\r
@@ -391,10 +419,7 @@ CreateIdentityMappingPageTables (
         PageDirectoryPointerEntry->Bits.Present = 1;\r
 \r
         for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {\r
         PageDirectoryPointerEntry->Bits.Present = 1;\r
 \r
         for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {\r
-          if ((IsNullDetectionEnabled () && PageAddress == 0)\r
-              || (PcdGetBool (PcdSetNxForStack)\r
-                  && (PageAddress < StackBase + StackSize)\r
-                  && ((PageAddress + SIZE_2MB) > StackBase))) {\r
+          if (ToSplitPageTable (PageAddress, SIZE_2MB, StackBase, StackSize)) {\r
             //\r
             // Need to split this 2M page that covers NULL or stack range.\r
             //\r
             //\r
             // Need to split this 2M page that covers NULL or stack range.\r
             //\r