public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Taylor Beebe" <t@taylorbeebe.com>
To: devel@edk2.groups.io
Cc: Jian J Wang <jian.j.wang@intel.com>,
	Liming Gao <gaoliming@byosoft.com.cn>,
	Dandan Bi <dandan.bi@intel.com>
Subject: [PATCH 01/14] MdeModulePkg: Add DXE and MM Memory Protection Settings Definitions
Date: Tue, 11 Jul 2023 16:52:38 -0700	[thread overview]
Message-ID: <90e3068695d8dc23c940e7f8ad00a7efc6d91bd6.1689101263.git.t@taylorbeebe.com> (raw)
In-Reply-To: <cover.1689101263.git.t@taylorbeebe.com>

From: Taylor Beebe <tabeebe@microsoft.com>

These headers provide settings definitions for memory protections,
settings profiles for easily enabling memory protections,
and the GUIDs used for producing the memory protection HOB.

The settings options are functionally 1:1 with the existing
PCD bitfield definitions. Instead of setting a fixed at build
PCD, memory protection settings will be created via a HOB
at runtime.

Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
 .../Guid/DxeMemoryProtectionSettings.h        | 413 ++++++++++++++++++
 .../Include/Guid/MmMemoryProtectionSettings.h | 211 +++++++++
 MdeModulePkg/MdeModulePkg.dec                 |  10 +
 3 files changed, 634 insertions(+)
 create mode 100644 MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h
 create mode 100644 MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h

diff --git a/MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h b/MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h
new file mode 100644
index 0000000000..93144494d5
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h
@@ -0,0 +1,413 @@
+/** @file
+
+Defines memory protection settings guid and struct for DXE.
+
+Copyright (C) Microsoft Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef DXE_MEMORY_PROTECTION_SETTINGS_H_
+#define DXE_MEMORY_PROTECTION_SETTINGS_H_
+
+#include <Library/BaseMemoryLib.h>
+
+// Current iteration of DXE_MEMORY_PROTECTION_SETTINGS
+#define DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION  1
+
+#define OEM_RESERVED_MPS_MEMORY_TYPE     EfiMaxMemoryType
+#define OS_RESERVED_MPS_MEMORY_TYPE      (EfiMaxMemoryType + 1)
+#define MAX_DXE_MPS_MEMORY_TYPE          (EfiMaxMemoryType + 2)
+#define DXE_MPS_MEMORY_TYPE_BUFFER_SIZE  (MAX_DXE_MPS_MEMORY_TYPE * sizeof (BOOLEAN))
+
+typedef struct {
+  BOOLEAN    Enabled            : 1;
+  BOOLEAN    DisableEndOfDxe    : 1;
+  BOOLEAN    NonstopModeEnabled : 1;
+} DXE_NULL_DETECTION_POLICY;
+
+typedef struct {
+  BOOLEAN    ProtectImageFromUnknown : 1;
+  BOOLEAN    ProtectImageFromFv      : 1;
+} DXE_IMAGE_PROTECTION_POLICY;
+
+typedef struct {
+  BOOLEAN    PageGuardEnabled        : 1;
+  BOOLEAN    PoolGuardEnabled        : 1;
+  BOOLEAN    FreedMemoryGuardEnabled : 1;
+  BOOLEAN    NonstopModeEnabled      : 1;
+  BOOLEAN    GuardAlignedToTail      : 1;
+} DXE_HEAP_GUARD_POLICY;
+
+typedef struct {
+  BOOLEAN    EnabledForType[MAX_DXE_MPS_MEMORY_TYPE];
+} DXE_MPS_MEMORY_TYPES;
+
+typedef UINT8 DXE_MEMORY_PROTECTION_SETTINGS_VERSION;
+
+//
+// Memory Protection Settings struct
+//
+typedef struct {
+  // The current version of the structure definition. This is used to ensure there isn't a
+  // definition mismatch if modules have differing iterations of this header. When creating
+  // this struct, use the DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION macro.
+  DXE_MEMORY_PROTECTION_SETTINGS_VERSION    StructVersion;
+
+  // If enabled, the page at the top of the stack will be invalidated to catch stack overflow.
+  BOOLEAN                                   CpuStackGuardEnabled;
+
+  // If enabled, the stack will be marked non-executable.
+  BOOLEAN                                   StackExecutionProtectionEnabled;
+
+  // If enabled, accessing the NULL address in UEFI will be caught by marking
+  // the NULL page as not present.
+  //   .NullDetectionEnabled    : Enable NULL pointer detection.
+  //   .DisableEndOfDxe         : Disable NULL pointer detection just after EndOfDxe.
+  //                              This is a workaround for those unsolvable NULL access issues in
+  //                              OptionROM, boot loader, etc. It can also help to avoid unnecessary
+  //                              exception caused by legacy memory (0-4095) access after EndOfDxe,
+  //                              such as Windows 7 boot on Qemu.
+  //   .NonstopModeEnabled      : If enabled the debug flag will be raised when a fault occurs
+  //                              to break into debugger.
+  DXE_NULL_DETECTION_POLICY    NullPointerDetection;
+
+  // Set image protection policy.
+  //
+  //  .ProtectImageFromUnknown          : If set, images from unknown devices will be protected by
+  //                                      DxeCore if they are aligned. The code section becomes
+  //                                      read-only, and the data section becomes non-executable.
+  //  .ProtectImageFromFv               : If set, images from firmware volumes will be protected by
+  //                                      DxeCore if they are aligned. The code section becomes
+  //                                      read-only, and the data section becomes non-executable.
+  DXE_IMAGE_PROTECTION_POLICY    ImageProtection;
+
+  // If a bit is set, memory regions of the associated type will be mapped non-executable.
+  //
+  // The execution protection setting for EfiBootServicesData and EfiConventionalMemory must
+  // be the same.
+  DXE_MPS_MEMORY_TYPES           ExecutionProtection;
+
+  //  Configures general heap guard behavior.
+  //
+  //  .PageGuardEnabled         : Enable page guard.
+  //  .PoolGuardEnabled         : Enable pool guard.
+  //  .FreedMemoryGuardEnabled  : Enable freed-memory guard (Use-After-Free memory detection).
+  //  .NonstopModeEnabled       : If enabled the debug flag will be raised when a fault occurs
+  //                              to break into debugger.
+  //  .GuardAlignedToTail       : TRUE if the pool is aligned to tail guard page. If FALSE, the
+  //                              pool is aligned to head guard page.
+  //
+  //  Note:
+  //  a) Due to the limit of pool memory implementation and the alignment
+  //     requirement of UEFI spec, HeapGuard.GuardAlignedToTail is a try-best
+  //     setting which cannot guarantee that the returned pool is exactly
+  //     adjacent to head or tail guard page.
+  //  b) Freed-memory guard and pool/page guard cannot be enabled
+  //     at the same time.
+  DXE_HEAP_GUARD_POLICY    HeapGuard;
+
+  // Indicates which type allocation need guard page.
+  //
+  // If bit is set, a head guard page and a tail guard page will be added just
+  // before and after corresponding type of pages which the allocated pool occupies,
+  // if there's enough free memory for all of them.
+  //
+  // These settings are only valid if HeapGuard.PoolGuardEnabled is TRUE.
+  DXE_MPS_MEMORY_TYPES    PoolGuard;
+
+  // Indicates which type allocation need guard page.
+  //
+  // If a bit is set, a head guard page and a tail guard page will be added just
+  // before and after corresponding type of pages allocated if there's enough
+  // free pages for all of them.
+  //
+  // These settings are only valid if HeapGuard.PageGuardEnabled is TRUE.
+  DXE_MPS_MEMORY_TYPES    PageGuard;
+} DXE_MEMORY_PROTECTION_SETTINGS;
+
+#define DXE_MPS_IS_STRUCT_VALID(DxeMpsPtr) \
+  (((DXE_MEMORY_PROTECTION_SETTINGS *)DxeMpsPtr)->StructVersion == DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION)
+
+#define DXE_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(MpsMemoryTypesPtr) \
+  (!IsZeroBuffer (&((DXE_MPS_MEMORY_TYPES *)MpsMemoryTypesPtr)->EnabledForType, DXE_MPS_MEMORY_TYPE_BUFFER_SIZE))
+
+#define DXE_MPS_IS_IMAGE_PROTECTION_ENABLED(DxeMpsPtr) \
+  (((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->ImageProtection.ProtectImageFromFv || \
+  ((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->ImageProtection.ProtectImageFromUnknown)
+
+#define DXE_MPS_IS_EXECUTION_PROTECTION_ENABLED(DxeMpsPtr) \
+  DXE_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->ExecutionProtection)
+
+#define DXE_MPS_ARE_PAGE_GUARDS_ENABLED(DxeMpsPtr) \
+  (((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->HeapGuard.PageGuardEnabled  && \
+  DXE_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->PageGuard))
+
+#define DXE_MPS_ARE_POOL_GUARDS_ENABLED(DxeMpsPtr) \
+  (((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->HeapGuard.PoolGuardEnabled  && \
+  DXE_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->PoolGuard))
+
+#define DXE_MPS_IS_MEMORY_PROTECTION_ACTIVE(DxeMpsPtr)                                   \
+  (DXE_MPS_IS_STRUCT_VALID(DxeMpsPtr)                                               &&   \
+   (((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->CpuStackGuardEnabled              ||   \
+    ((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->StackExecutionProtectionEnabled   ||   \
+    ((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->NullPointerDetection.Enabled      ||   \
+    DXE_MPS_IS_IMAGE_PROTECTION_ENABLED(DxeMpsPtr)                                  ||   \
+    DXE_MPS_IS_EXECUTION_PROTECTION_ENABLED(DxeMpsPtr)                              ||   \
+    DXE_MPS_ARE_PAGE_GUARDS_ENABLED(DxeMpsPtr)                                      ||   \
+    DXE_MPS_ARE_POOL_GUARDS_ENABLED(DxeMpsPtr))                                          \
+  )
+
+#define HOB_DXE_MEMORY_PROTECTION_SETTINGS_GUID  \
+  { \
+    { 0x9ABFD639, 0xD1D0, 0x4EFF, { 0xBD, 0xB6, 0x7E, 0xC4, 0x19, 0x0D, 0x17, 0xD5 } } \
+  }
+
+extern GUID  gDxeMemoryProtectionSettingsGuid;
+
+//
+//  A memory profile with strict settings ideal for development scenarios.
+//
+#define DXE_MEMORY_PROTECTION_SETTINGS_DEBUG  {                 \
+            DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,     \
+            TRUE, /* Stack Guard */                             \
+            TRUE, /* Stack Execution Protection */              \
+            {     /* NULL Pointer Detection */                  \
+              .Enabled                                = TRUE,   \
+              .DisableEndOfDxe                        = FALSE,  \
+              .NonstopModeEnabled                     = TRUE    \
+            },                                                  \
+            { /* Image Protection */                            \
+              .ProtectImageFromUnknown                = TRUE,   \
+              .ProtectImageFromFv                     = TRUE    \
+            },                                                  \
+            { /* Execution Protection */                        \
+              .EnabledForType = {                               \
+                [EfiReservedMemoryType]               = TRUE,   \
+                [EfiLoaderCode]                       = FALSE,  \
+                [EfiLoaderData]                       = TRUE,   \
+                [EfiBootServicesCode]                 = FALSE,  \
+                [EfiBootServicesData]                 = TRUE,   \
+                [EfiRuntimeServicesCode]              = FALSE,  \
+                [EfiRuntimeServicesData]              = TRUE,   \
+                [EfiConventionalMemory]               = TRUE,   \
+                [EfiUnusableMemory]                   = TRUE,   \
+                [EfiACPIReclaimMemory]                = TRUE,   \
+                [EfiACPIMemoryNVS]                    = TRUE,   \
+                [EfiMemoryMappedIO]                   = TRUE,   \
+                [EfiMemoryMappedIOPortSpace]          = TRUE,   \
+                [EfiPalCode]                          = TRUE,   \
+                [EfiPersistentMemory]                 = FALSE,  \
+                [EfiUnacceptedMemoryType]             = TRUE,   \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]        = TRUE,   \
+                [OS_RESERVED_MPS_MEMORY_TYPE]         = TRUE    \
+              }                                                 \
+            },                                                  \
+            { /* Heap Guard */                                  \
+              .PageGuardEnabled                       = TRUE,   \
+              .PoolGuardEnabled                       = TRUE,   \
+              .FreedMemoryGuardEnabled                = FALSE,  \
+              .NonstopModeEnabled                     = TRUE,   \
+              .GuardAlignedToTail                     = FALSE   \
+            },                                                  \
+            { /* Pool Guard */                                  \
+              .EnabledForType = {                               \
+                [EfiReservedMemoryType]               = TRUE,   \
+                [EfiLoaderCode]                       = TRUE,   \
+                [EfiLoaderData]                       = TRUE,   \
+                [EfiBootServicesCode]                 = TRUE,   \
+                [EfiBootServicesData]                 = TRUE,   \
+                [EfiRuntimeServicesCode]              = TRUE,   \
+                [EfiRuntimeServicesData]              = TRUE,   \
+                [EfiConventionalMemory]               = FALSE,  \
+                [EfiUnusableMemory]                   = TRUE,   \
+                [EfiACPIReclaimMemory]                = TRUE,   \
+                [EfiACPIMemoryNVS]                    = TRUE,   \
+                [EfiMemoryMappedIO]                   = TRUE,   \
+                [EfiMemoryMappedIOPortSpace]          = TRUE,   \
+                [EfiPalCode]                          = TRUE,   \
+                [EfiPersistentMemory]                 = FALSE,  \
+                [EfiUnacceptedMemoryType]             = TRUE,   \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]        = TRUE,   \
+                [OS_RESERVED_MPS_MEMORY_TYPE]         = TRUE    \
+              }                                                 \
+            },                                                  \
+            { /* Page Guard */                                  \
+              .EnabledForType = {                               \
+                [EfiReservedMemoryType]               = TRUE,   \
+                [EfiLoaderCode]                       = TRUE,   \
+                [EfiLoaderData]                       = TRUE,   \
+                [EfiBootServicesCode]                 = TRUE,   \
+                [EfiBootServicesData]                 = TRUE,   \
+                [EfiRuntimeServicesCode]              = TRUE,   \
+                [EfiRuntimeServicesData]              = TRUE,   \
+                [EfiConventionalMemory]               = FALSE,  \
+                [EfiUnusableMemory]                   = TRUE,   \
+                [EfiACPIReclaimMemory]                = TRUE,   \
+                [EfiACPIMemoryNVS]                    = TRUE,   \
+                [EfiMemoryMappedIO]                   = TRUE,   \
+                [EfiMemoryMappedIOPortSpace]          = TRUE,   \
+                [EfiPalCode]                          = TRUE,   \
+                [EfiPersistentMemory]                 = FALSE,  \
+                [EfiUnacceptedMemoryType]             = TRUE,   \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]        = TRUE,   \
+                [OS_RESERVED_MPS_MEMORY_TYPE]         = TRUE    \
+              }                                                 \
+            }                                                   \
+          };
+
+//
+//  A memory profile recommended for production. Compared to the debug
+//  settings, this profile removes the pool guards and uses page guards
+//  for fewer memory types.
+//
+#define DXE_MEMORY_PROTECTION_SETTINGS_PROD_MODE                \
+          {                                                     \
+            DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,     \
+            TRUE, /* Stack Guard */                             \
+            TRUE, /* Stack Execution Protection */              \
+            {     /* NULL Pointer Detection */                  \
+              .Enabled                                = TRUE,   \
+              .DisableEndOfDxe                        = FALSE,  \
+              .NonstopModeEnabled                     = FALSE   \
+            },                                                  \
+            { /* Image Protection */                            \
+              .ProtectImageFromUnknown                = FALSE,  \
+              .ProtectImageFromFv                     = TRUE    \
+            },                                                  \
+            { /* Execution Protection */                        \
+              .EnabledForType = {                               \
+                [EfiReservedMemoryType]               = TRUE,   \
+                [EfiLoaderCode]                       = FALSE,  \
+                [EfiLoaderData]                       = TRUE,   \
+                [EfiBootServicesCode]                 = FALSE,  \
+                [EfiBootServicesData]                 = TRUE,   \
+                [EfiRuntimeServicesCode]              = FALSE,  \
+                [EfiRuntimeServicesData]              = TRUE,   \
+                [EfiConventionalMemory]               = TRUE,   \
+                [EfiUnusableMemory]                   = TRUE,   \
+                [EfiACPIReclaimMemory]                = TRUE,   \
+                [EfiACPIMemoryNVS]                    = TRUE,   \
+                [EfiMemoryMappedIO]                   = TRUE,   \
+                [EfiMemoryMappedIOPortSpace]          = TRUE,   \
+                [EfiPalCode]                          = TRUE,   \
+                [EfiPersistentMemory]                 = FALSE,  \
+                [EfiUnacceptedMemoryType]             = TRUE,   \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]        = TRUE,   \
+                [OS_RESERVED_MPS_MEMORY_TYPE]         = TRUE    \
+              }                                                 \
+            },                                                  \
+            { /* Heap Guard */                                  \
+              .PageGuardEnabled                       = TRUE,   \
+              .PoolGuardEnabled                       = FALSE,  \
+              .FreedMemoryGuardEnabled                = FALSE,  \
+              .NonstopModeEnabled                     = FALSE,  \
+              .GuardAlignedToTail                     = FALSE   \
+            },                                                  \
+            { /* Pool Guard */                                  \
+              0                                                 \
+            },                                                  \
+            { /* Page Guard */                                  \
+              .EnabledForType = {                               \
+                [EfiReservedMemoryType]               = FALSE,  \
+                [EfiLoaderCode]                       = FALSE,  \
+                [EfiLoaderData]                       = FALSE,  \
+                [EfiBootServicesCode]                 = FALSE,  \
+                [EfiBootServicesData]                 = TRUE,   \
+                [EfiRuntimeServicesCode]              = FALSE,  \
+                [EfiRuntimeServicesData]              = TRUE,   \
+                [EfiConventionalMemory]               = FALSE,  \
+                [EfiUnusableMemory]                   = FALSE,  \
+                [EfiACPIReclaimMemory]                = FALSE,  \
+                [EfiACPIMemoryNVS]                    = FALSE,  \
+                [EfiMemoryMappedIO]                   = FALSE,  \
+                [EfiMemoryMappedIOPortSpace]          = FALSE,  \
+                [EfiPalCode]                          = FALSE,  \
+                [EfiPersistentMemory]                 = FALSE,  \
+                [EfiUnacceptedMemoryType]             = FALSE,  \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]        = FALSE,  \
+                [OS_RESERVED_MPS_MEMORY_TYPE]         = FALSE   \
+              }                                                 \
+            }                                                   \
+          };
+
+//
+//  A memory profile which mirrors DXE_MEMORY_PROTECTION_SETTINGS_PROD_MODE
+//  but doesn't include page guards.
+//
+#define DXE_MEMORY_PROTECTION_SETTINGS_PROD_MODE_NO_PAGE_GUARDS \
+          {                                                     \
+            DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,     \
+            TRUE, /* Stack Guard */                             \
+            TRUE, /* Stack Execution Protection */              \
+            {     /* NULL Pointer Detection */                  \
+              .Enabled                                = TRUE,   \
+              .DisableEndOfDxe                        = FALSE,  \
+              .NonstopModeEnabled                     = FALSE   \
+            },                                                  \
+            { /* Image Protection */                            \
+              .ProtectImageFromUnknown                = FALSE,  \
+              .ProtectImageFromFv                     = TRUE    \
+            },                                                  \
+            { /* Execution Protection */                        \
+              .EnabledForType = {                               \
+                [EfiReservedMemoryType]               = TRUE,   \
+                [EfiLoaderCode]                       = FALSE,  \
+                [EfiLoaderData]                       = TRUE,   \
+                [EfiBootServicesCode]                 = FALSE,  \
+                [EfiBootServicesData]                 = TRUE,   \
+                [EfiRuntimeServicesCode]              = FALSE,  \
+                [EfiRuntimeServicesData]              = TRUE,   \
+                [EfiConventionalMemory]               = TRUE,   \
+                [EfiUnusableMemory]                   = TRUE,   \
+                [EfiACPIReclaimMemory]                = TRUE,   \
+                [EfiACPIMemoryNVS]                    = TRUE,   \
+                [EfiMemoryMappedIO]                   = TRUE,   \
+                [EfiMemoryMappedIOPortSpace]          = TRUE,   \
+                [EfiPalCode]                          = TRUE,   \
+                [EfiPersistentMemory]                 = FALSE,  \
+                [EfiUnacceptedMemoryType]             = TRUE,   \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]        = TRUE,   \
+                [OS_RESERVED_MPS_MEMORY_TYPE]         = TRUE    \
+              }                                                 \
+            },                                                  \
+            { /* Heap Guard */                                  \
+              0                                                 \
+            },                                                  \
+            { /* Pool Guard */                                  \
+              0                                                 \
+            },                                                  \
+            { /* Page Guard */                                  \
+              0                                                 \
+            }                                                   \
+          };
+
+//
+//  A memory profile which disables all DXE memory protection settings.
+//
+#define DXE_MEMORY_PROTECTION_SETTINGS_OFF                      \
+          {                                                     \
+            DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,     \
+            FALSE, /* Stack Guard */                            \
+            FALSE, /* Stack Execution Protection */             \
+            {      /* NULL Pointer Detection */                 \
+              0                                                 \
+            },                                                  \
+            { /* Image Protection */                            \
+              0                                                 \
+            },                                                  \
+            { /* Execution Protection */                        \
+              0                                                 \
+            },                                                  \
+            { /* Heap Guard */                                  \
+              0                                                 \
+            },                                                  \
+            { /* Pool Guard */                                  \
+              0                                                 \
+            },                                                  \
+            { /* Page Guard */                                  \
+              0                                                 \
+            }                                                   \
+          };
+
+#endif
diff --git a/MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h b/MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h
new file mode 100644
index 0000000000..383788b8f3
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h
@@ -0,0 +1,211 @@
+/** @file
+
+Defines memory protection settings guid and struct for MM.
+
+Copyright (C) Microsoft Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_MEMORY_PROTECTION_SETTINGS_H_
+#define MM_MEMORY_PROTECTION_SETTINGS_H_
+
+#include <Library/BaseMemoryLib.h>
+
+// Current iteration of MM_MEMORY_PROTECTION_SETTINGS
+#define MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION  1
+
+#define OEM_RESERVED_MPS_MEMORY_TYPE    EfiMaxMemoryType
+#define OS_RESERVED_MPS_MEMORY_TYPE     (EfiMaxMemoryType + 1)
+#define MAX_MM_MPS_MEMORY_TYPE          (EfiMaxMemoryType + 2)
+#define MM_MPS_MEMORY_TYPE_BUFFER_SIZE  (MAX_MM_MPS_MEMORY_TYPE * sizeof (BOOLEAN))
+
+typedef struct {
+  BOOLEAN    Enabled            : 1;
+  BOOLEAN    NonstopModeEnabled : 1;
+} MM_NULL_DETECTION_POLICY;
+
+typedef struct {
+  BOOLEAN    PageGuardEnabled   : 1;
+  BOOLEAN    PoolGuardEnabled   : 1;
+  BOOLEAN    NonstopModeEnabled : 1;
+  BOOLEAN    GuardAlignedToTail : 1;
+} MM_HEAP_GUARD_POLICY;
+
+typedef struct {
+  BOOLEAN    EnabledForType[MAX_MM_MPS_MEMORY_TYPE];
+} MM_MPS_MEMORY_TYPES;
+
+typedef UINT8 MM_MEMORY_PROTECTION_SETTINGS_VERSION;
+
+//
+// Memory Protection Settings struct
+//
+typedef struct {
+  // The current version of the structure definition. This is used to ensure there isn't a
+  // definition mismatch if modules have differing iterations of this header. When creating
+  // this struct, use the MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION macro.
+  MM_MEMORY_PROTECTION_SETTINGS_VERSION    StructVersion;
+
+  // If enabled, accessing the NULL address in MM will be caught by marking
+  // the NULL page as not present.
+  //   .NullDetectionEnabled    : Enable NULL pointer detection.
+  //   .NonstopModeEnabled      : If enabled the debug flag will be raised when a fault occurs
+  //                              to break into debugger.
+  MM_NULL_DETECTION_POLICY                 NullPointerDetection;
+
+  //  Configures general heap guard behavior.
+  //
+  // Note:
+  //  a) Due to the limit of pool memory implementation and the alignment
+  //     requirement of UEFI spec, HeapGuard.GuardAlignedToTail is a try-best
+  //     setting which cannot guarantee that the returned pool is exactly
+  //     adjacent to head or tail guard page.
+  //
+  //  .PageGuardEnabled          : Enable page guard.
+  //  .PoolGuardEnabled          : Enable pool guard.
+  //  .NonstopModeEnabled        : If enabled the debug flag will be raised when a fault occurs
+  //                               to break into debugger.
+  //  .GuardAlignedToTail        : TRUE if the pool is aligned to tail guard page. If FALSE, the
+  //                               pool is aligned to head guard page.
+  MM_HEAP_GUARD_POLICY    HeapGuard;
+
+  // Indicates which type allocation need guard page.
+  //
+  // If bit is set, a head guard page and a tail guard page will be added just
+  // before and after corresponding type of pages which the allocated pool occupies,
+  // if there's enough free memory for all of them.
+  //
+  // These settings are only valid if PoolGuardEnabled is TRUE in HeapGuard.
+  MM_MPS_MEMORY_TYPES    PoolGuard;
+
+  // Indicates which type allocation need guard page.
+  //
+  // If a bit is set, a head guard page and a tail guard page will be added just
+  // before and after corresponding type of pages allocated if there's enough
+  // free pages for all of them.
+  //
+  // This bitfield is only valid if PageGuardEnabled is TRUE in HeapGuard.
+  MM_MPS_MEMORY_TYPES    PageGuard;
+} MM_MEMORY_PROTECTION_SETTINGS;
+
+#define MM_MPS_IS_STRUCT_VALID(MmMpsPtr) \
+  (((MM_MEMORY_PROTECTION_SETTINGS *)MmMpsPtr)->StructVersion == MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION)
+
+#define MM_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(MpsMemoryTypesPtr) \
+  (!IsZeroBuffer (&((MM_MPS_MEMORY_TYPES *)MpsMemoryTypesPtr)->EnabledForType, MM_MPS_MEMORY_TYPE_BUFFER_SIZE))
+
+#define MM_MPS_IS_IMAGE_PROTECTION_ENABLED(MmMpsPtr) \
+  (((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->ImageProtection.ProtectImageFromFv || \
+  ((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->ImageProtection.ProtectImageFromUnknown)
+
+#define MM_MPS_IS_EXECUTION_PROTECTION_ENABLED(MmMpsPtr) \
+  MM_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->ExecutionProtection)
+
+#define MM_MPS_ARE_PAGE_GUARDS_ENABLED(MmMpsPtr) \
+  (((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->HeapGuard.PageGuardEnabled  && \
+  MM_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->PageGuard))
+
+#define MM_MPS_ARE_POOL_GUARDS_ENABLED(MmMpsPtr) \
+  (((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->HeapGuard.PoolGuardEnabled  && \
+  MM_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->PoolGuard))
+
+#define MM_MPS_IS_MEMORY_PROTECTION_ACTIVE(MmMpsPtr)                                   \
+  (MM_MPS_IS_STRUCT_VALID(MmMpsPtr)                                               &&   \
+   (((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->CpuStackGuardEnabled              ||   \
+    ((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->StackExecutionProtectionEnabled   ||   \
+    ((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->NullPointerDetection.Enabled      ||   \
+    MM_MPS_IS_IMAGE_PROTECTION_ENABLED(MmMpsPtr)                                  ||   \
+    MM_MPS_IS_EXECUTION_PROTECTION_ENABLED(MmMpsPtr)                              ||   \
+    MM_MPS_ARE_PAGE_GUARDS_ENABLED(MmMpsPtr)                                      ||   \
+    MM_MPS_ARE_POOL_GUARDS_ENABLED(MmMpsPtr))                                          \
+  )
+
+#define HOB_MM_MEMORY_PROTECTION_SETTINGS_GUID \
+  { \
+    { 0x0CF445DD, 0xA67C, 0x4F8C, { 0x81, 0x9B, 0xB7, 0xB6, 0x86, 0xED, 0x7C, 0x75 } } \
+  }
+
+extern GUID  gMmMemoryProtectionSettingsGuid;
+
+//
+//  A memory profile ideal for development scenarios.
+//
+#define MM_MEMORY_PROTECTION_SETTINGS_DEBUG  {               \
+            MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,   \
+            { /* NULL Pointer Detection */                   \
+              .Enabled                             = TRUE,   \
+              .NonstopModeEnabled                  = TRUE    \
+            },                                               \
+            { /* Heap Guard */                               \
+              .PageGuardEnabled                    = TRUE,   \
+              .PoolGuardEnabled                    = TRUE,   \
+              .NonstopModeEnabled                  = TRUE,   \
+              .GuardAlignedToTail                  = FALSE   \
+            },                                               \
+            { /* Pool Guard */                               \
+              .EnabledForType = {                            \
+                [EfiReservedMemoryType]            = FALSE,  \
+                [EfiLoaderCode]                    = FALSE,  \
+                [EfiLoaderData]                    = FALSE,  \
+                [EfiBootServicesCode]              = FALSE,  \
+                [EfiBootServicesData]              = TRUE,   \
+                [EfiRuntimeServicesCode]           = FALSE,  \
+                [EfiRuntimeServicesData]           = TRUE,   \
+                [EfiConventionalMemory]            = FALSE,  \
+                [EfiUnusableMemory]                = FALSE,  \
+                [EfiACPIReclaimMemory]             = FALSE,  \
+                [EfiACPIMemoryNVS]                 = FALSE,  \
+                [EfiMemoryMappedIO]                = FALSE,  \
+                [EfiMemoryMappedIOPortSpace]       = FALSE,  \
+                [EfiPalCode]                       = FALSE,  \
+                [EfiPersistentMemory]              = FALSE,  \
+                [EfiUnacceptedMemoryType]          = FALSE,  \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]     = FALSE,  \
+                [OS_RESERVED_MPS_MEMORY_TYPE]      = FALSE   \
+              }                                              \
+            },                                               \
+            { /* Page Guard */                               \
+              .EnabledForType = {                            \
+                [EfiReservedMemoryType]            = FALSE,  \
+                [EfiLoaderCode]                    = FALSE,  \
+                [EfiLoaderData]                    = FALSE,  \
+                [EfiBootServicesCode]              = FALSE,  \
+                [EfiBootServicesData]              = TRUE,   \
+                [EfiRuntimeServicesCode]           = FALSE,  \
+                [EfiRuntimeServicesData]           = TRUE,   \
+                [EfiConventionalMemory]            = FALSE,  \
+                [EfiUnusableMemory]                = FALSE,  \
+                [EfiACPIReclaimMemory]             = FALSE,  \
+                [EfiACPIMemoryNVS]                 = FALSE,  \
+                [EfiMemoryMappedIO]                = FALSE,  \
+                [EfiMemoryMappedIOPortSpace]       = FALSE,  \
+                [EfiPalCode]                       = FALSE,  \
+                [EfiPersistentMemory]              = FALSE,  \
+                [EfiUnacceptedMemoryType]          = FALSE,  \
+                [OEM_RESERVED_MPS_MEMORY_TYPE]     = FALSE,  \
+                [OS_RESERVED_MPS_MEMORY_TYPE]      = FALSE   \
+              }                                              \
+            }                                                \
+          }
+
+//
+//  A memory profile which disables all MM memory protection settings.
+//
+#define MM_MEMORY_PROTECTION_SETTINGS_OFF  {                 \
+            MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,   \
+            { /* NULL Pointer Detection */                   \
+              0                                              \
+            },                                               \
+            { /* Heap Guard */                               \
+              0                                              \
+            },                                               \
+            { /* Pool Guard */                               \
+              0                                              \
+            },                                               \
+            { /* Page Guard */                               \
+              0                                              \
+            }                                                \
+          }
+
+#endif
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index d65dae18aa..f8c0fb4e93 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -399,6 +399,16 @@
   ## Include/Guid/EndofS3Resume.h
   gEdkiiEndOfS3ResumeGuid = { 0x96f5296d, 0x05f7, 0x4f3c, {0x84, 0x67, 0xe4, 0x56, 0x89, 0x0e, 0x0c, 0xb5 } }
 
+  ## DXE Memory Protection Settings Guid. Used to create and fetch the DXE memory protection settings HOB entry.
+  #
+  # Include/Guid/DxeMemoryProtectionSettings
+  gDxeMemoryProtectionSettingsGuid = { 0x9ABFD639, 0xD1D0, 0x4EFF, { 0xBD, 0xB6, 0x7E, 0xC4, 0x19, 0x0D, 0x17, 0xD5 }}
+
+  ## SMM Memory Protection Settings Guid. Used to create and fetch the SMM memory protection settings HOB entry.
+  #
+  # Include/Guid/MmMemoryProtectionSettings
+  gMmMemoryProtectionSettingsGuid = { 0x0CF445DD, 0xA67C, 0x4F8C, { 0x81, 0x9B, 0xB7, 0xB6, 0x86, 0xED, 0x7C, 0x75 }}
+
   ## Used (similar to Variable Services) to communicate policies to the enforcement engine.
   # {DA1B0D11-D1A7-46C4-9DC9-F3714875C6EB}
   gVarCheckPolicyLibMmiHandlerGuid = { 0xda1b0d11, 0xd1a7, 0x46c4, { 0x9d, 0xc9, 0xf3, 0x71, 0x48, 0x75, 0xc6, 0xeb }}
-- 
2.41.0.windows.2


  reply	other threads:[~2023-07-11 23:53 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
2023-07-11 23:52 ` Taylor Beebe [this message]
2023-07-11 23:52 ` [PATCH 02/14] MdeModulePkg: Add MemoryProtectionHobLib Definitions and NULL Libs Taylor Beebe
2023-07-11 23:52 ` [PATCH 03/14] MdeModulePkg: Add Phase-Specific MemoryProtectionHobLib Implementations Taylor Beebe
2023-07-11 23:52 ` [PATCH 04/14] OvmfPkg: Create the memory protection settings HOB Taylor Beebe
2023-07-11 23:52 ` [PATCH 05/14] ArmVirtPkg: Create " Taylor Beebe
2023-07-11 23:52 ` [PATCH 06/14] ArmPkg: Update to use memory protection HOB Taylor Beebe
2023-07-11 23:52 ` [PATCH 07/14] EmulatorPkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 08/14] MdeModulePkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 09/14] OvmfPkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 10/14] UefiCpuPkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 11/14] UefiPayloadPkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 12/14] OvmfPkg: Delete Memory Protection PCDs Taylor Beebe
2023-07-11 23:52 ` [PATCH 14/14] MdeModulePkg: " Taylor Beebe
2023-07-11 23:52 ` Taylor Beebe
     [not found] ` <1770F551E2E594C0.16575@groups.io>
2023-07-12  0:01   ` [edk2-devel] " Taylor Beebe
2023-07-12 10:05 ` [PATCH 00/14] Implement Dynamic Memory Protections Gerd Hoffmann
2023-07-12 21:54   ` Taylor Beebe
2023-07-17 11:14     ` [edk2-devel] " Gerd Hoffmann
2023-07-17 16:15 ` Pedro Falcato
2023-07-17 16:25   ` Ard Biesheuvel
2023-07-17 16:49     ` Pedro Falcato
2023-07-18  2:45       ` Taylor Beebe
2023-07-18  6:11     ` Ni, Ray

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=90e3068695d8dc23c940e7f8ad00a7efc6d91bd6.1689101263.git.t@taylorbeebe.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