public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH] MdeModulePkg/DxeIpl: support more NX related PCDs
@ 2018-09-14  5:13 Jian J Wang
  2018-09-14  5:46 ` Wang, Jian J
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Jian J Wang @ 2018-09-14  5:13 UTC (permalink / raw)
  To: edk2-devel; +Cc: Star Zeng, Laszlo Ersek, Ard Biesheuvel, Ruiyu Ni, Jiewen Yao

BZ#1116: https://bugzilla.tianocore.org/show_bug.cgi?id=1116

Currently IA32_EFER.NXE is only set against PcdSetNxForStack. This
confuses developers because following two other PCDs also need NXE
to be set, but actually not.

    PcdDxeNxMemoryProtectionPolicy
    PcdImageProtectionPolicy

This patch solves this issue by adding logic to enable IA32_EFER.NXE
if any of those PCDs have anything enabled.

Due to the fact that NX memory type of stack (enabled by PcdSetNxForStack)
and image data section (enabled by PcdImageProtectionPolicy) are also
part of PcdDxeNxMemoryProtectionPolicy, this patch also add more checks
to warn (ASSERT) users any unreasonable setting combinations. For example,

    PcdSetNxForStack == FALSE &&
      (PcdDxeNxMemoryProtectionPolicy & (1 <<EfiBootServicesData)) != 0

    PcdImageProtectionPolicy == 0 &&
      (PcdDxeNxMemoryProtectionPolicy & (1 << EfiRuntimeServicesData)) != 0

    PcdImageProtectionPolicy == 0 &&
      (PcdDxeNxMemoryProtectionPolicy & (1 <<EfiBootServicesData)) != 0

    PcdImageProtectionPolicy == 0 &&
      (PcdDxeNxMemoryProtectionPolicy & (1 <<EfiLoaderData)) != 0

In other words, PcdSetNxForStack and PcdImageProtectionPolicy have
priority over PcdDxeNxMemoryProtectionPolicy.

Cc: Star Zeng <star.zeng@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Jiewen Yao <jiewen.yao@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          |  2 +
 MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c  |  4 +-
 MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c | 55 +++++++++++++++++++++++-
 MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h | 33 ++++++++++++++
 4 files changed, 91 insertions(+), 3 deletions(-)

diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
index fd82657404..068e700074 100644
--- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
@@ -117,6 +117,8 @@
 
 [Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64]
   gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack               ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy       ## SOMETIMES_CONSUMES
 
 [Depex]
   gEfiPeiLoadFilePpiGuid AND gEfiPeiMasterBootModePpiGuid
diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
index d28baa3615..9a97205ef8 100644
--- a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
@@ -245,7 +245,7 @@ ToBuildPageTable (
     return TRUE;
   }
 
-  if (PcdGetBool (PcdSetNxForStack) && IsExecuteDisableBitAvailable ()) {
+  if (ToEnableExecuteDisableFeature ()) {
     return TRUE;
   }
 
@@ -436,7 +436,7 @@ HandOffToDxeCore (
     BuildPageTablesIa32Pae = ToBuildPageTable ();
     if (BuildPageTablesIa32Pae) {
       PageTables = Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE);
-      if (IsExecuteDisableBitAvailable ()) {
+      if (ToEnableExecuteDisableFeature ()) {
         EnableExecuteDisableBit();
       }
     }
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
index 496e219913..253fe84223 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
@@ -106,6 +106,56 @@ IsNullDetectionEnabled (
   return ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT0) != 0);
 }
 
+/**
+  Check if Execute Disable Bit (IA32_EFER.NXE) should be enabled or not.
+
+  @retval TRUE    IA32_EFER.NXE should be enabled.
+  @retval FALSE   IA32_EFER.NXE should not be enabled.
+
+**/
+BOOLEAN
+ToEnableExecuteDisableFeature (
+  VOID
+  )
+{
+  if (!IsExecuteDisableBitAvailable ()) {
+    return FALSE;
+  }
+
+  //
+  // Normally stack is type of EfiBootServicesData. Disabling NX for stack
+  // but enabling NX for EfiBootServicesData doesn't make any sense.
+  //
+  if (PcdGetBool (PcdSetNxForStack) == FALSE &&
+      (PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & STACK_MEMORY_TYPE) != 0) {
+    DEBUG ((DEBUG_ERROR,
+            "ERROR: NX for stack is disabled but NX for its memory type is enabled!\r\n"));
+    ASSERT(!(PcdGetBool (PcdSetNxForStack) == FALSE &&
+             (PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & STACK_MEMORY_TYPE) != 0));
+  }
+
+  //
+  // Image data section could be type of EfiLoaderData, EfiBootServicesData
+  // or EfiRuntimeServicesData. Disabling NX for image data but enabling NX
+  // for any those memory types doesn't make any sense.
+  //
+  if (PcdGet32 (PcdImageProtectionPolicy) == 0 &&
+      (PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & IMAGE_DATA_MEMORY_TYPE) != 0) {
+    DEBUG ((DEBUG_ERROR,
+            "ERROR: NX for image data is disabled but NX for its memory type(s) is enabled!\r\n"));
+    ASSERT (!(PcdGet32 (PcdImageProtectionPolicy) == 0 &&
+              (PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & IMAGE_DATA_MEMORY_TYPE) != 0));
+  }
+
+  //
+  // XD flag (BIT63) in page table entry is only valid if IA32_EFER.NXE is set.
+  // Features controlled by Following PCDs need this feature to be enabled.
+  //
+  return (PcdGetBool (PcdSetNxForStack) ||
+          PcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0 ||
+          PcdGet32 (PcdImageProtectionPolicy) != 0);
+}
+
 /**
   Enable Execute Disable Bit.
 
@@ -755,7 +805,10 @@ CreateIdentityMappingPageTables (
   //
   EnablePageTableProtection ((UINTN)PageMap, TRUE);
 
-  if (PcdGetBool (PcdSetNxForStack)) {
+  //
+  // Set IA32_EFER.NXE if necessary.
+  //
+  if (ToEnableExecuteDisableFeature ()) {
     EnableExecuteDisableBit ();
   }
 
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h
index 85457ff937..9f152e6531 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h
@@ -179,6 +179,39 @@ typedef struct {
   UINTN           FreePages;
 } PAGE_TABLE_POOL;
 
+//
+// Bit field repsentations of some EFI_MEMORY_TYPE, for page table initialization.
+//
+#define STACK_MEMORY_TYPE           (1 << EfiBootServicesData)    /* 0x10 */
+#define IMAGE_DATA_MEMORY_TYPE      ((1 << EfiLoaderData)       | /* 0x04 */\
+                                     (1 << EfiBootServicesData) | /* 0x10 */\
+                                     (1 << EfiRuntimeServicesData)/* 0x40 */\
+                                    )                             /* 0x54 */
+
+/**
+  Check if Execute Disable Bit (IA32_EFER.NXE) should be enabled or not.
+
+  @retval TRUE    IA32_EFER.NXE should be enabled.
+  @retval FALSE   IA32_EFER.NXE should not be enabled.
+
+**/
+BOOLEAN
+ToEnableExecuteDisableFeature (
+  VOID
+  );
+
+/**
+  The function will check if Execute Disable Bit is available.
+
+  @retval TRUE      Execute Disable Bit is available.
+  @retval FALSE     Execute Disable Bit is not available.
+
+**/
+BOOLEAN
+IsExecuteDisableBitAvailable (
+  VOID
+  );
+
 /**
   Enable Execute Disable Bit.
 
-- 
2.16.2.windows.1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2018-09-19 11:39 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-09-14  5:13 [PATCH] MdeModulePkg/DxeIpl: support more NX related PCDs Jian J Wang
2018-09-14  5:46 ` Wang, Jian J
2018-09-14  6:04 ` Ard Biesheuvel
2018-09-14  6:50   ` Wang, Jian J
2018-09-14  9:27     ` Laszlo Ersek
2018-09-17  1:00       ` Wang, Jian J
2018-09-14  9:50 ` Laszlo Ersek
2018-09-17  2:11   ` Wang, Jian J
2018-09-17  5:57     ` Zeng, Star
2018-09-17 10:13       ` Laszlo Ersek
2018-09-18  1:21         ` Wang, Jian J
2018-09-18  8:46           ` Zeng, Star
2018-09-19  9:13             ` Wang, Jian J
2018-09-19 11:39               ` Laszlo Ersek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox