[edk2-devel] [PATCH v1 1/3] MdeModulePkg: Add DXE and MM Memory Protection Settings HOB Definitions

Taylor Beebe posted 3 patches 2 years, 8 months ago
[edk2-devel] [PATCH v1 1/3] MdeModulePkg: Add DXE and MM Memory Protection Settings HOB Definitions
Posted by Taylor Beebe 2 years, 8 months ago
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>
---
 MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h | 503 ++++++++++++++++++++
 MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h  | 239 ++++++++++
 MdeModulePkg/MdeModulePkg.dec                           |  10 +
 3 files changed, 752 insertions(+)

diff --git a/MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h b/MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h
new file mode 100644
index 000000000000..7f4b573805a8
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h
@@ -0,0 +1,503 @@
+/** @file
+
+Defines memory protection settings guid and struct
+
+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_
+
+typedef union {
+  UINT8    Data;
+  struct {
+    UINT8    NullDetectionEnabled : 1;
+    UINT8    DisableEndOfDxe      : 1;
+    UINT8    NonstopModeEnabled   : 1;
+  } Fields;
+} DXE_NULL_DETECTION_POLICY;
+
+typedef union {
+  UINT8    Data;
+  struct {
+    UINT8    PageGuardEnabled        : 1;
+    UINT8    PoolGuardEnabled        : 1;
+    UINT8    FreedMemoryGuardEnabled : 1;
+    UINT8    NonstopModeEnabled      : 1;
+    UINT8    GuardAlignment          : 1;
+  } Fields;
+} DXE_HEAP_GUARD_POLICY;
+
+typedef union {
+  UINT32    Data;
+  struct {
+    UINT8    EfiReservedMemoryType      : 1;
+    UINT8    EfiLoaderCode              : 1;
+    UINT8    EfiLoaderData              : 1;
+    UINT8    EfiBootServicesCode        : 1;
+    UINT8    EfiBootServicesData        : 1;
+    UINT8    EfiRuntimeServicesCode     : 1;
+    UINT8    EfiRuntimeServicesData     : 1;
+    UINT8    EfiConventionalMemory      : 1;
+    UINT8    EfiUnusableMemory          : 1;
+    UINT8    EfiACPIReclaimMemory       : 1;
+    UINT8    EfiACPIMemoryNVS           : 1;
+    UINT8    EfiMemoryMappedIO          : 1;
+    UINT8    EfiMemoryMappedIOPortSpace : 1;
+    UINT8    EfiPalCode                 : 1;
+    UINT8    EfiPersistentMemory        : 1;
+    UINT8    OEMReserved                : 1;
+    UINT8    OSReserved                 : 1;
+  } Fields;
+} DXE_HEAP_GUARD_MEMORY_TYPES;
+
+typedef union {
+  UINT8    Data;
+  struct {
+    UINT8    ProtectImageFromUnknown : 1;
+    UINT8    ProtectImageFromFv      : 1;
+  } Fields;
+} DXE_IMAGE_PROTECTION_POLICY;
+
+typedef UINT8 DXE_MEMORY_PROTECTION_SETTINGS_VERSION;
+
+#define DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION  1 // Current iteration of DXE_MEMORY_PROTECTION_SETTINGS
+
+//
+// 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;
+
+  // Indicates if UEFI Stack Guard will be enabled.
+  //
+  // If enabled, stack overflow in UEFI can be caught.
+  //  TRUE  - UEFI Stack Guard will be enabled.
+  //  FALSE - UEFI Stack Guard will be disabled.
+  BOOLEAN                                   CpuStackGuard;
+
+  // Bitfield to control the NULL address detection in code for different phases.
+  // If enabled, accessing NULL address in UEFI or SMM code can be caught by marking
+  // the NULL page as not present.
+  //   .NullDetectionEnabled    : Enable NULL pointer detection for UEFI.
+  //   .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      : Enable UEFI non-stop mode. If enabled, UEFI will raise the debug flag
+  //                              to break into debugger when a fault occurs.
+  DXE_NULL_DETECTION_POLICY    NullPointerDetectionPolicy;
+
+  // Bitfield to control Heap Guard behavior.
+  //
+  // Note:
+  //  a) Due to the limit of pool memory implementation and the alignment
+  //     requirement of UEFI spec, HeapGuardPolicy.GuardAlignment is a try-best
+  //     setting which cannot guarantee that the returned pool is exactly
+  //     adjacent to head guard page or tail guard page.
+  //  b) UEFI freed-memory guard and UEFI pool/page guard cannot be enabled
+  //     at the same time.
+  //
+  //  .PageGuardEnabled         : Enable UEFI page guard.
+  //  .PoolGuardEnabled         : Enable UEFI pool guard.
+  //  .FreedMemoryGuardEnabled  : Enable UEFI freed-memory guard (Use-After-Free memory detection).
+  //  .NonstopModeEnabled       : Enable UEFI non-stop mode. If enabled, the debug flag will be raised
+  //                              to break into debugger when a fault occurs.
+  //  .GuardAlignment           : The alignment of Guard Page for Pool Guard.
+  //                              0 - The returned pool is near the tail guard page.
+  //                              1 - The returned pool is near the head guard page.
+  DXE_HEAP_GUARD_POLICY    HeapGuardPolicy;
+
+  // 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.
+  //
+  // Note: If a bit is cleared, an image data section could be still non-executable if
+  // NxProtectionPolicy is enabled for EfiLoaderData, EfiBootServicesData or EfiRuntimeServicesData.
+  DXE_IMAGE_PROTECTION_POLICY    ImageProtectionPolicy;
+
+  // 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. The pool allocation for the
+  // type related to cleared bits keeps the same as ususal.
+  //
+  // This bitfield is only valid if PoolGuardEnabled and/or PoolGuardEnabled are set in HeapGuardPolicy.
+  DXE_HEAP_GUARD_MEMORY_TYPES    HeapGuardPoolType;
+
+  // 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. The page allocation for the type related to
+  // cleared bits keeps the same as ususal.
+  //
+  // This bitfield is only valid if PageGuardEnabled is set in HeapGuardPolicy.
+  DXE_HEAP_GUARD_MEMORY_TYPES    HeapGuardPageType;
+
+  // DXE no execute memory protection policy.
+  //
+  // If a bit is set, memory regions of the associated type will be mapped
+  // non-executable. If a bit is cleared, nothing will be done to associated type of memory.
+  //
+  // NOTE: User MUST set the same NX protection for EfiBootServicesData and EfiConventionalMemory.
+  DXE_HEAP_GUARD_MEMORY_TYPES    NxProtectionPolicy;
+} DXE_MEMORY_PROTECTION_SETTINGS;
+
+#define HOB_DXE_MEMORY_PROTECTION_SETTINGS_GUID \
+  { \
+    { 0x9ABFD639, 0xD1D0, 0x4EFF, { 0xBD, 0xB6, 0x7E, 0xC4, 0x19, 0x0D, 0x17, 0xD5 } } \
+  }
+
+extern GUID  gDxeMemoryProtectionSettingsGuid;
+
+// HeapGuardPolicy.Fields.GuardAlignment value indicating tail alignment
+#define POOL_ALIGNED_TO_TAIL_GUARD  0
+
+// HeapGuardPolicy.Fields.GuardAlignment value indicating head alignment
+#define POOL_ALIGNED_TO_HEAD_GUARD  1
+
+//
+//  A memory profile with strict settings.
+//
+#define DXE_MEMORY_PROTECTION_SETTINGS_DEBUG                    \
+          {                                                     \
+            DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,     \
+            TRUE,   /* Stack Guard On */                        \
+            {                                                   \
+              .Fields.NullDetectionEnabled            = 1,      \
+              .Fields.DisableEndOfDxe                 = 0,      \
+              .Fields.NonstopModeEnabled              = 1       \
+            },                                                  \
+            {                                                   \
+              .Fields.PageGuardEnabled                = 1,      \
+              .Fields.PoolGuardEnabled                = 1,      \
+              .Fields.FreedMemoryGuardEnabled         = 0,      \
+              .Fields.NonstopModeEnabled              = 1,      \
+              .Fields.GuardAlignment                  = 0       \
+            },                                                  \
+            {                                                   \
+              .Fields.ProtectImageFromUnknown         = 1,      \
+              .Fields.ProtectImageFromFv              = 1,      \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType           = 1,      \
+              .Fields.EfiLoaderCode                   = 1,      \
+              .Fields.EfiLoaderData                   = 1,      \
+              .Fields.EfiBootServicesCode             = 1,      \
+              .Fields.EfiBootServicesData             = 1,      \
+              .Fields.EfiRuntimeServicesCode          = 1,      \
+              .Fields.EfiRuntimeServicesData          = 1,      \
+              .Fields.EfiConventionalMemory           = 0,      \
+              .Fields.EfiUnusableMemory               = 1,      \
+              .Fields.EfiACPIReclaimMemory            = 1,      \
+              .Fields.EfiACPIMemoryNVS                = 1,      \
+              .Fields.EfiMemoryMappedIO               = 1,      \
+              .Fields.EfiMemoryMappedIOPortSpace      = 1,      \
+              .Fields.EfiPalCode                      = 1,      \
+              .Fields.EfiPersistentMemory             = 0,      \
+              .Fields.OEMReserved                     = 1,      \
+              .Fields.OSReserved                      = 1       \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType           = 1,      \
+              .Fields.EfiLoaderCode                   = 1,      \
+              .Fields.EfiLoaderData                   = 1,      \
+              .Fields.EfiBootServicesCode             = 1,      \
+              .Fields.EfiBootServicesData             = 1,      \
+              .Fields.EfiRuntimeServicesCode          = 1,      \
+              .Fields.EfiRuntimeServicesData          = 1,      \
+              .Fields.EfiConventionalMemory           = 0,      \
+              .Fields.EfiUnusableMemory               = 1,      \
+              .Fields.EfiACPIReclaimMemory            = 1,      \
+              .Fields.EfiACPIMemoryNVS                = 1,      \
+              .Fields.EfiMemoryMappedIO               = 1,      \
+              .Fields.EfiMemoryMappedIOPortSpace      = 1,      \
+              .Fields.EfiPalCode                      = 1,      \
+              .Fields.EfiPersistentMemory             = 0,      \
+              .Fields.OEMReserved                     = 1,      \
+              .Fields.OSReserved                      = 1       \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType           = 1,      \
+              .Fields.EfiLoaderCode                   = 1,      \
+              .Fields.EfiLoaderData                   = 1,      \
+              .Fields.EfiBootServicesCode             = 1,      \
+              .Fields.EfiBootServicesData             = 1,      \
+              .Fields.EfiRuntimeServicesCode          = 1,      \
+              .Fields.EfiRuntimeServicesData          = 1,      \
+              .Fields.EfiConventionalMemory           = 1,      \
+              .Fields.EfiUnusableMemory               = 1,      \
+              .Fields.EfiACPIReclaimMemory            = 1,      \
+              .Fields.EfiACPIMemoryNVS                = 1,      \
+              .Fields.EfiMemoryMappedIO               = 1,      \
+              .Fields.EfiMemoryMappedIOPortSpace      = 1,      \
+              .Fields.EfiPalCode                      = 1,      \
+              .Fields.EfiPersistentMemory             = 0,      \
+              .Fields.OEMReserved                     = 1,      \
+              .Fields.OSReserved                      = 1       \
+            }                                                   \
+          }
+
+//
+//  A memory profile recommended for production. Compared to the debug
+//  settings, this 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 On */                        \
+            {                                                   \
+              .Fields.NullDetectionEnabled            = 1,      \
+              .Fields.DisableEndOfDxe                 = 0,      \
+              .Fields.NonstopModeEnabled              = 0       \
+            },                                                  \
+            {                                                   \
+              .Fields.PageGuardEnabled                = 1,      \
+              .Fields.PoolGuardEnabled                = 0,      \
+              .Fields.FreedMemoryGuardEnabled         = 0,      \
+              .Fields.NonstopModeEnabled              = 0,      \
+              .Fields.GuardAlignment                  = 0       \
+            },                                                  \
+            {                                                   \
+              .Fields.ProtectImageFromUnknown         = 0,      \
+              .Fields.ProtectImageFromFv              = 1,      \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType           = 0,      \
+              .Fields.EfiLoaderCode                   = 0,      \
+              .Fields.EfiLoaderData                   = 0,      \
+              .Fields.EfiBootServicesCode             = 0,      \
+              .Fields.EfiBootServicesData             = 0,      \
+              .Fields.EfiRuntimeServicesCode          = 0,      \
+              .Fields.EfiRuntimeServicesData          = 0,      \
+              .Fields.EfiConventionalMemory           = 0,      \
+              .Fields.EfiUnusableMemory               = 0,      \
+              .Fields.EfiACPIReclaimMemory            = 0,      \
+              .Fields.EfiACPIMemoryNVS                = 0,      \
+              .Fields.EfiMemoryMappedIO               = 0,      \
+              .Fields.EfiMemoryMappedIOPortSpace      = 0,      \
+              .Fields.EfiPalCode                      = 0,      \
+              .Fields.EfiPersistentMemory             = 0,      \
+              .Fields.OEMReserved                     = 0,      \
+              .Fields.OSReserved                      = 0       \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType           = 0,      \
+              .Fields.EfiLoaderCode                   = 0,      \
+              .Fields.EfiLoaderData                   = 0,      \
+              .Fields.EfiBootServicesCode             = 0,      \
+              .Fields.EfiBootServicesData             = 1,      \
+              .Fields.EfiRuntimeServicesCode          = 0,      \
+              .Fields.EfiRuntimeServicesData          = 1,      \
+              .Fields.EfiConventionalMemory           = 0,      \
+              .Fields.EfiUnusableMemory               = 0,      \
+              .Fields.EfiACPIReclaimMemory            = 0,      \
+              .Fields.EfiACPIMemoryNVS                = 0,      \
+              .Fields.EfiMemoryMappedIO               = 0,      \
+              .Fields.EfiMemoryMappedIOPortSpace      = 0,      \
+              .Fields.EfiPalCode                      = 0,      \
+              .Fields.EfiPersistentMemory             = 0,      \
+              .Fields.OEMReserved                     = 0,      \
+              .Fields.OSReserved                      = 0       \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType           = 1,      \
+              .Fields.EfiLoaderCode                   = 1,      \
+              .Fields.EfiLoaderData                   = 1,      \
+              .Fields.EfiBootServicesCode             = 1,      \
+              .Fields.EfiBootServicesData             = 1,      \
+              .Fields.EfiRuntimeServicesCode          = 1,      \
+              .Fields.EfiRuntimeServicesData          = 1,      \
+              .Fields.EfiConventionalMemory           = 1,      \
+              .Fields.EfiUnusableMemory               = 1,      \
+              .Fields.EfiACPIReclaimMemory            = 1,      \
+              .Fields.EfiACPIMemoryNVS                = 1,      \
+              .Fields.EfiMemoryMappedIO               = 1,      \
+              .Fields.EfiMemoryMappedIOPortSpace      = 1,      \
+              .Fields.EfiPalCode                      = 1,      \
+              .Fields.EfiPersistentMemory             = 1,      \
+              .Fields.OEMReserved                     = 0,      \
+              .Fields.OSReserved                      = 0       \
+            }                                                   \
+          }
+
+//
+//  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 On */                        \
+            {                                                   \
+              .Fields.NullDetectionEnabled            = 1,      \
+              .Fields.DisableEndOfDxe                 = 0,      \
+              .Fields.NonstopModeEnabled              = 0       \
+            },                                                  \
+            {                                                   \
+              .Fields.PageGuardEnabled                = 0,      \
+              .Fields.PoolGuardEnabled                = 0,      \
+              .Fields.FreedMemoryGuardEnabled         = 0,      \
+              .Fields.NonstopModeEnabled              = 0,      \
+              .Fields.GuardAlignment                  = 0       \
+            },                                                  \
+            {                                                   \
+              .Fields.ProtectImageFromUnknown         = 0,      \
+              .Fields.ProtectImageFromFv              = 1,      \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType           = 0,      \
+              .Fields.EfiLoaderCode                   = 0,      \
+              .Fields.EfiLoaderData                   = 0,      \
+              .Fields.EfiBootServicesCode             = 0,      \
+              .Fields.EfiBootServicesData             = 0,      \
+              .Fields.EfiRuntimeServicesCode          = 0,      \
+              .Fields.EfiRuntimeServicesData          = 0,      \
+              .Fields.EfiConventionalMemory           = 0,      \
+              .Fields.EfiUnusableMemory               = 0,      \
+              .Fields.EfiACPIReclaimMemory            = 0,      \
+              .Fields.EfiACPIMemoryNVS                = 0,      \
+              .Fields.EfiMemoryMappedIO               = 0,      \
+              .Fields.EfiMemoryMappedIOPortSpace      = 0,      \
+              .Fields.EfiPalCode                      = 0,      \
+              .Fields.EfiPersistentMemory             = 0,      \
+              .Fields.OEMReserved                     = 0,      \
+              .Fields.OSReserved                      = 0       \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType           = 0,      \
+              .Fields.EfiLoaderCode                   = 0,      \
+              .Fields.EfiLoaderData                   = 0,      \
+              .Fields.EfiBootServicesCode             = 0,      \
+              .Fields.EfiBootServicesData             = 0,      \
+              .Fields.EfiRuntimeServicesCode          = 0,      \
+              .Fields.EfiRuntimeServicesData          = 0,      \
+              .Fields.EfiConventionalMemory           = 0,      \
+              .Fields.EfiUnusableMemory               = 0,      \
+              .Fields.EfiACPIReclaimMemory            = 0,      \
+              .Fields.EfiACPIMemoryNVS                = 0,      \
+              .Fields.EfiMemoryMappedIO               = 0,      \
+              .Fields.EfiMemoryMappedIOPortSpace      = 0,      \
+              .Fields.EfiPalCode                      = 0,      \
+              .Fields.EfiPersistentMemory             = 0,      \
+              .Fields.OEMReserved                     = 0,      \
+              .Fields.OSReserved                      = 0       \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType           = 1,      \
+              .Fields.EfiLoaderCode                   = 0,      \
+              .Fields.EfiLoaderData                   = 1,      \
+              .Fields.EfiBootServicesCode             = 0,      \
+              .Fields.EfiBootServicesData             = 1,      \
+              .Fields.EfiRuntimeServicesCode          = 0,      \
+              .Fields.EfiRuntimeServicesData          = 1,      \
+              .Fields.EfiConventionalMemory           = 1,      \
+              .Fields.EfiUnusableMemory               = 1,      \
+              .Fields.EfiACPIReclaimMemory            = 1,      \
+              .Fields.EfiACPIMemoryNVS                = 1,      \
+              .Fields.EfiMemoryMappedIO               = 1,      \
+              .Fields.EfiMemoryMappedIOPortSpace      = 1,      \
+              .Fields.EfiPalCode                      = 1,      \
+              .Fields.EfiPersistentMemory             = 1,      \
+              .Fields.OEMReserved                     = 0,      \
+              .Fields.OSReserved                      = 0       \
+            }                                                   \
+          }
+
+//
+//  A memory profile which disables all memory protection settings.
+//
+#define DXE_MEMORY_PROTECTION_SETTINGS_OFF                      \
+          {                                                     \
+            DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,     \
+            FALSE,  /* Stack Guard On */                        \
+            {                                                   \
+              .Fields.NullDetectionEnabled            = 0,      \
+              .Fields.DisableEndOfDxe                 = 0,      \
+              .Fields.NonstopModeEnabled              = 0       \
+            },                                                  \
+            {                                                   \
+              .Fields.PageGuardEnabled                = 0,      \
+              .Fields.PoolGuardEnabled                = 0,      \
+              .Fields.FreedMemoryGuardEnabled         = 0,      \
+              .Fields.NonstopModeEnabled              = 0,      \
+              .Fields.GuardAlignment                  = 0       \
+            },                                                  \
+            {                                                   \
+              .Fields.ProtectImageFromUnknown         = 0,      \
+              .Fields.ProtectImageFromFv              = 0,      \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType           = 0,      \
+              .Fields.EfiLoaderCode                   = 0,      \
+              .Fields.EfiLoaderData                   = 0,      \
+              .Fields.EfiBootServicesCode             = 0,      \
+              .Fields.EfiBootServicesData             = 0,      \
+              .Fields.EfiRuntimeServicesCode          = 0,      \
+              .Fields.EfiRuntimeServicesData          = 0,      \
+              .Fields.EfiConventionalMemory           = 0,      \
+              .Fields.EfiUnusableMemory               = 0,      \
+              .Fields.EfiACPIReclaimMemory            = 0,      \
+              .Fields.EfiACPIMemoryNVS                = 0,      \
+              .Fields.EfiMemoryMappedIO               = 0,      \
+              .Fields.EfiMemoryMappedIOPortSpace      = 0,      \
+              .Fields.EfiPalCode                      = 0,      \
+              .Fields.EfiPersistentMemory             = 0,      \
+              .Fields.OEMReserved                     = 0,      \
+              .Fields.OSReserved                      = 0       \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType           = 0,      \
+              .Fields.EfiLoaderCode                   = 0,      \
+              .Fields.EfiLoaderData                   = 0,      \
+              .Fields.EfiBootServicesCode             = 0,      \
+              .Fields.EfiBootServicesData             = 0,      \
+              .Fields.EfiRuntimeServicesCode          = 0,      \
+              .Fields.EfiRuntimeServicesData          = 0,      \
+              .Fields.EfiConventionalMemory           = 0,      \
+              .Fields.EfiUnusableMemory               = 0,      \
+              .Fields.EfiACPIReclaimMemory            = 0,      \
+              .Fields.EfiACPIMemoryNVS                = 0,      \
+              .Fields.EfiMemoryMappedIO               = 0,      \
+              .Fields.EfiMemoryMappedIOPortSpace      = 0,      \
+              .Fields.EfiPalCode                      = 0,      \
+              .Fields.EfiPersistentMemory             = 0,      \
+              .Fields.OEMReserved                     = 0,      \
+              .Fields.OSReserved                      = 0       \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType           = 0,      \
+              .Fields.EfiLoaderCode                   = 0,      \
+              .Fields.EfiLoaderData                   = 0,      \
+              .Fields.EfiBootServicesCode             = 0,      \
+              .Fields.EfiBootServicesData             = 0,      \
+              .Fields.EfiRuntimeServicesCode          = 0,      \
+              .Fields.EfiRuntimeServicesData          = 0,      \
+              .Fields.EfiConventionalMemory           = 0,      \
+              .Fields.EfiUnusableMemory               = 0,      \
+              .Fields.EfiACPIReclaimMemory            = 0,      \
+              .Fields.EfiACPIMemoryNVS                = 0,      \
+              .Fields.EfiMemoryMappedIO               = 0,      \
+              .Fields.EfiMemoryMappedIOPortSpace      = 0,      \
+              .Fields.EfiPalCode                      = 0,      \
+              .Fields.EfiPersistentMemory             = 0,      \
+              .Fields.OEMReserved                     = 0,      \
+              .Fields.OSReserved                      = 0       \
+            }                                                   \
+          }
+
+#endif
diff --git a/MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h b/MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h
new file mode 100644
index 000000000000..77c362afcc1e
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h
@@ -0,0 +1,239 @@
+/** @file
+
+Defines memory protection settings guid and struct
+
+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_
+
+typedef union {
+  UINT8    Data;
+  struct {
+    UINT8    NullDetectionEnabled : 1;
+    UINT8    NonstopModeEnabled   : 1;
+  } Fields;
+} MM_NULL_DETECTION_POLICY;
+
+typedef union {
+  UINT8    Data;
+  struct {
+    UINT8    PageGuardEnabled   : 1;
+    UINT8    PoolGuardEnabled   : 1;
+    UINT8    NonstopModeEnabled : 1;
+    UINT8    GuardAlignment     : 1;
+  } Fields;
+} MM_HEAP_GUARD_POLICY;
+
+typedef union {
+  UINT32    Data;
+  struct {
+    UINT8    EfiReservedMemoryType      : 1;
+    UINT8    EfiLoaderCode              : 1;
+    UINT8    EfiLoaderData              : 1;
+    UINT8    EfiBootServicesCode        : 1;
+    UINT8    EfiBootServicesData        : 1;
+    UINT8    EfiRuntimeServicesCode     : 1;
+    UINT8    EfiRuntimeServicesData     : 1;
+    UINT8    EfiConventionalMemory      : 1;
+    UINT8    EfiUnusableMemory          : 1;
+    UINT8    EfiACPIReclaimMemory       : 1;
+    UINT8    EfiACPIMemoryNVS           : 1;
+    UINT8    EfiMemoryMappedIO          : 1;
+    UINT8    EfiMemoryMappedIOPortSpace : 1;
+    UINT8    EfiPalCode                 : 1;
+    UINT8    EfiPersistentMemory        : 1;
+    UINT8    OEMReserved                : 1;
+    UINT8    OSReserved                 : 1;
+  } Fields;
+} MM_HEAP_GUARD_MEMORY_TYPES;
+
+typedef UINT8 MM_MEMORY_PROTECTION_SETTINGS_VERSION;
+
+#define MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION  1 // Current iteration of MM_MEMORY_PROTECTION_SETTINGS
+
+//
+// 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 NULL address in UEFI or SMM code can be caught by marking
+  // the NULL page as not present.
+  //
+  //   .NullDetectionEnabled      : Enable MM NULL detection.
+  //   .NonstopModeEnabled        : Enable MM non-stop mode. If enabled, the debug flag will be raised
+  //                                to break into debugger when a fault occurs.
+  MM_NULL_DETECTION_POLICY                 NullPointerDetectionPolicy;
+
+  // Bitfield to control Heap Guard behavior.
+  //
+  // Note:
+  //  a) Due to the limit of pool memory implementation and the alignment
+  //     requirement of UEFI spec, HeapGuardPolicy.GuardAlignment is a try-best
+  //     setting which cannot guarantee that the returned pool is exactly
+  //     adjacent to head guard page or tail guard page.
+  //
+  //  .PageGuardEnabled          : Enable MM page guard.
+  //  .PoolGuardEnabled          : Enable MM pool guard.
+  //  .NonstopModeEnabled        : Enable MM non-stop mode. If enabled, the debug flag will be raised
+  //                               to break into debugger when a fault occurs.
+  //  .GuardAlignment            : The alignment of Guard Page for Pool Guard.
+  //                               0 - The returned pool is near the tail guard page.
+  //                               1 - The returned pool is near the head guard page.
+  MM_HEAP_GUARD_POLICY    HeapGuardPolicy;
+
+  // 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. The pool allocation for the
+  // type related to cleared bits keeps the same as ususal.
+  //
+  // This bitfield is only valid if PoolGuardEnabled and/or PoolGuardEnabled are set in HeapGuardPolicy.
+  MM_HEAP_GUARD_MEMORY_TYPES    HeapGuardPoolType;
+
+  // 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. The page allocation for the type related to
+  // cleared bits keeps the same as ususal.
+  //
+  // This bitfield is only valid if PageGuardEnabled is set in HeapGuardPolicy.
+  MM_HEAP_GUARD_MEMORY_TYPES    HeapGuardPageType;
+} MM_MEMORY_PROTECTION_SETTINGS;
+
+#define HOB_MM_MEMORY_PROTECTION_SETTINGS_GUID \
+  { \
+    { 0x0CF445DD, 0xA67C, 0x4F8C, { 0x81, 0x9B, 0xB7, 0xB6, 0x86, 0xED, 0x7C, 0x75 } } \
+  }
+
+extern GUID  gMmMemoryProtectionSettingsGuid;
+
+// HeapGuardPolicy.Fields.GuardAlignment value indicating tail alignment
+#define HEAP_GUARD_ALIGNED_TO_TAIL  0
+
+// HeapGuardPolicy.Fields.GuardAlignment value indicating head alignment
+#define HEAP_GUARD_ALIGNED_TO_HEAD  1
+
+//
+//  An MM memory profile with strict settings. This will likely add to the
+//  total boot time but will catch more configuration and memory errors.
+//
+#define MM_MEMORY_PROTECTION_SETTINGS_DEBUG                     \
+          {                                                     \
+            MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,      \
+            {                                                   \
+              .Fields.NullDetectionEnabled         = 1,         \
+              .Fields.NonstopModeEnabled           = 1          \
+            },                                                  \
+            {                                                   \
+              .Fields.PageGuardEnabled             = 1,         \
+              .Fields.PoolGuardEnabled             = 1,         \
+              .Fields.NonstopModeEnabled           = 1,         \
+              .Fields.GuardAlignment               = 0          \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType        = 0,         \
+              .Fields.EfiLoaderCode                = 0,         \
+              .Fields.EfiLoaderData                = 0,         \
+              .Fields.EfiBootServicesCode          = 0,         \
+              .Fields.EfiBootServicesData          = 1,         \
+              .Fields.EfiRuntimeServicesCode       = 0,         \
+              .Fields.EfiRuntimeServicesData       = 1,         \
+              .Fields.EfiConventionalMemory        = 0,         \
+              .Fields.EfiUnusableMemory            = 0,         \
+              .Fields.EfiACPIReclaimMemory         = 0,         \
+              .Fields.EfiACPIMemoryNVS             = 0,         \
+              .Fields.EfiMemoryMappedIO            = 0,         \
+              .Fields.EfiMemoryMappedIOPortSpace   = 0,         \
+              .Fields.EfiPalCode                   = 0,         \
+              .Fields.EfiPersistentMemory          = 0,         \
+              .Fields.OEMReserved                  = 0,         \
+              .Fields.OSReserved                   = 0          \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType        = 0,         \
+              .Fields.EfiLoaderCode                = 0,         \
+              .Fields.EfiLoaderData                = 0,         \
+              .Fields.EfiBootServicesCode          = 0,         \
+              .Fields.EfiBootServicesData          = 1,         \
+              .Fields.EfiRuntimeServicesCode       = 0,         \
+              .Fields.EfiRuntimeServicesData       = 1,         \
+              .Fields.EfiConventionalMemory        = 0,         \
+              .Fields.EfiUnusableMemory            = 0,         \
+              .Fields.EfiACPIReclaimMemory         = 0,         \
+              .Fields.EfiACPIMemoryNVS             = 0,         \
+              .Fields.EfiMemoryMappedIO            = 0,         \
+              .Fields.EfiMemoryMappedIOPortSpace   = 0,         \
+              .Fields.EfiPalCode                   = 0,         \
+              .Fields.EfiPersistentMemory          = 0,         \
+              .Fields.OEMReserved                  = 0,         \
+              .Fields.OSReserved                   = 0          \
+            }                                                   \
+          }
+
+//
+//  An SMM memory profile with all settings off.
+//
+#define MM_MEMORY_PROTECTION_SETTINGS_OFF                       \
+          {                                                     \
+            MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION,      \
+            {                                                   \
+              .Fields.NullDetectionEnabled         = 1,         \
+              .Fields.NonstopModeEnabled           = 0          \
+            },                                                  \
+            {                                                   \
+              .Fields.PageGuardEnabled             = 0,         \
+              .Fields.PoolGuardEnabled             = 0,         \
+              .Fields.NonstopModeEnabled           = 0,         \
+              .Fields.GuardAlignment               = 0          \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType        = 0,         \
+              .Fields.EfiLoaderCode                = 0,         \
+              .Fields.EfiLoaderData                = 0,         \
+              .Fields.EfiBootServicesCode          = 0,         \
+              .Fields.EfiBootServicesData          = 0,         \
+              .Fields.EfiRuntimeServicesCode       = 0,         \
+              .Fields.EfiRuntimeServicesData       = 0,         \
+              .Fields.EfiConventionalMemory        = 0,         \
+              .Fields.EfiUnusableMemory            = 0,         \
+              .Fields.EfiACPIReclaimMemory         = 0,         \
+              .Fields.EfiACPIMemoryNVS             = 0,         \
+              .Fields.EfiMemoryMappedIO            = 0,         \
+              .Fields.EfiMemoryMappedIOPortSpace   = 0,         \
+              .Fields.EfiPalCode                   = 0,         \
+              .Fields.EfiPersistentMemory          = 0,         \
+              .Fields.OEMReserved                  = 0,         \
+              .Fields.OSReserved                   = 0          \
+            },                                                  \
+            {                                                   \
+              .Fields.EfiReservedMemoryType        = 0,         \
+              .Fields.EfiLoaderCode                = 0,         \
+              .Fields.EfiLoaderData                = 0,         \
+              .Fields.EfiBootServicesCode          = 0,         \
+              .Fields.EfiBootServicesData          = 0,         \
+              .Fields.EfiRuntimeServicesCode       = 0,         \
+              .Fields.EfiRuntimeServicesData       = 0,         \
+              .Fields.EfiConventionalMemory        = 0,         \
+              .Fields.EfiUnusableMemory            = 0,         \
+              .Fields.EfiACPIReclaimMemory         = 0,         \
+              .Fields.EfiACPIMemoryNVS             = 0,         \
+              .Fields.EfiMemoryMappedIO            = 0,         \
+              .Fields.EfiMemoryMappedIOPortSpace   = 0,         \
+              .Fields.EfiPalCode                   = 0,         \
+              .Fields.EfiPersistentMemory          = 0,         \
+              .Fields.OEMReserved                  = 0,         \
+              .Fields.OSReserved                   = 0          \
+            }                                                   \
+          }
+
+#endif
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 95dd077e19b3..89001f217ed1 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -399,6 +399,16 @@ [Guids]
   ## 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.36.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#105987): https://edk2.groups.io/g/devel/message/105987
Mute This Topic: https://groups.io/mt/99437078/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-