MdeModulePkg/Core: fix feature conflict between NX and NULL detection
authorJian J Wang <jian.j.wang@intel.com>
Mon, 29 Jan 2018 11:07:29 +0000 (19:07 +0800)
committerStar Zeng <star.zeng@intel.com>
Fri, 2 Feb 2018 01:50:16 +0000 (09:50 +0800)
If enabled, NX memory protection feature will mark all free memory as
NX (non-executable), including page 0. This will overwrite the attributes
of page 0 if NULL pointer detection feature is also enabled and then
compromise the functionality of it. The solution is skipping the NX
attributes setting to page 0 if NULL pointer detection feature is enabled.

Cc: Star Zeng <star.zeng@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c

index 862593f..a4705bc 100644 (file)
@@ -845,10 +845,24 @@ InitializeDxeNxMemoryProtectionPolicy (
 \r
     Attributes = GetPermissionAttributeForMemoryType (MemoryMapEntry->Type);\r
     if (Attributes != 0) {\r
-      SetUefiImageMemoryAttributes (\r
-        MemoryMapEntry->PhysicalStart,\r
-        LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT),\r
-        Attributes);\r
+      if (MemoryMapEntry->PhysicalStart == 0 &&\r
+          PcdGet8 (PcdNullPointerDetectionPropertyMask) != 0) {\r
+\r
+        ASSERT (MemoryMapEntry->NumberOfPages > 0);\r
+        //\r
+        // Skip page 0 if NULL pointer detection is enabled to avoid attributes\r
+        // overwritten.\r
+        //\r
+        SetUefiImageMemoryAttributes (\r
+          MemoryMapEntry->PhysicalStart + EFI_PAGE_SIZE,\r
+          LShiftU64 (MemoryMapEntry->NumberOfPages - 1, EFI_PAGE_SHIFT),\r
+          Attributes);\r
+      } else {\r
+        SetUefiImageMemoryAttributes (\r
+          MemoryMapEntry->PhysicalStart,\r
+          LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT),\r
+          Attributes);\r
+      }\r
     }\r
     MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
   }\r