public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v1 0/3] MdeModulePkg: Adding Dynamic Memory Protection Settings Libraries
@ 2023-06-09 20:25 Taylor Beebe
  2023-06-09 20:25 ` [PATCH v1 1/3] MdeModulePkg: Add DXE and MM Memory Protection Settings HOB Definitions Taylor Beebe
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Taylor Beebe @ 2023-06-09 20:25 UTC (permalink / raw)
  To: devel
  Cc: Taylor Beebe, Jian J Wang, Liming Gao, Dandan Bi, Ard Biesheuvel,
	Ray Ni, Oliver Smith-Denny, Michael Kubacki, Kun Qin, Sean Brogan

Memory protection settings are currently configured via FixedAtBuild
PCDs which resulted in a build-time configuration of memory mitigations.
To improve flexibility and compatibility, this patchset adds HOB definitions
and libraries required for configuring memory protection settings at runtime.

Once the PCD references in the codebase are replaced with references to the
memory protection HOB entries, platforms will need to produce a HOB of the format
defined in DxeMemoryProtectionSettings.h and MmMemoryProtectionSettings.h.
For example, to enable strict protections in DXE the platform could do the
following:

DXE_MEMORY_PROTECTION_SETTINGS DxeSettings = (DXE_MEMORY_PROTECTION_SETTINGS)DXE_MEMORY_PROTECTION_SETTINGS_DEBUG;
BuildGuidDataHob (&gDxeMemoryProtectionSettingsGuid, &DxeSettings, sizeof (DxeSettings));

Deviations from the preset configurations are also easy, and analogous profiles are
provided for SMM and Standalone MM. A future patch series will replace
references to the memory protection PCDs with references to the HOB entry in the
codebase.

With the PCDs, the NX setting for EfiConventionalMemory
is checked with a call like:
PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & (1 << EfiConventionalMemory) != 0

Using the HOB, the NX setting for EfiConventionalMemory in the DXE environment
will be checked with a call like:
gDxeMps.NxProtectionPolicy.Fields.EfiConventionalMemory != 0

Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Oliver Smith-Denny <osd@smith-denny.com>
Cc: Michael Kubacki <mikuback@linux.microsoft.com>
Cc: Kun Qin <kuqin12@gmail.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>

Taylor Beebe (3):
  MdeModulePkg: Add DXE and MM Memory Protection Settings HOB
    Definitions
  MdeModulePkg: Add MemoryProtectionHobLib Definitions and NULL Libs
  MdeModulePkg: Add Phase-Specific MemoryProtectionHobLib
    Implementations

 MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.c            | 182 +++++++
 MdeModulePkg/Library/MemoryProtectionHobLib/MmCommonMemoryProtectionHobLib.c       | 139 ++++++
 MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.c            |  37 ++
 MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.c   |  37 ++
 MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.c    |  33 ++
 MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.c     |  33 ++
 MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h                            | 503 ++++++++++++++++++++
 MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h                             | 239 ++++++++++
 MdeModulePkg/Include/Library/DxeMemoryProtectionHobLib.h                           |  36 ++
 MdeModulePkg/Include/Library/MmMemoryProtectionHobLib.h                            |  36 ++
 MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf          |  34 ++
 MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf          |  35 ++
 MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf |  36 ++
 MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf  |  25 +
 MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf   |  26 +
 MdeModulePkg/MdeModulePkg.dec                                                      |  18 +
 MdeModulePkg/MdeModulePkg.dsc                                                      |  11 +
 17 files changed, 1460 insertions(+)
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/MmCommonMemoryProtectionHobLib.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.c
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.c
 create mode 100644 MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h
 create mode 100644 MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h
 create mode 100644 MdeModulePkg/Include/Library/DxeMemoryProtectionHobLib.h
 create mode 100644 MdeModulePkg/Include/Library/MmMemoryProtectionHobLib.h
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
 create mode 100644 MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf

-- 
2.36.1.windows.1


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

* [PATCH v1 1/3] MdeModulePkg: Add DXE and MM Memory Protection Settings HOB Definitions
  2023-06-09 20:25 [PATCH v1 0/3] MdeModulePkg: Adding Dynamic Memory Protection Settings Libraries Taylor Beebe
@ 2023-06-09 20:25 ` Taylor Beebe
  2023-06-09 20:26 ` [PATCH v1 2/3] MdeModulePkg: Add MemoryProtectionHobLib Definitions and NULL Libs Taylor Beebe
  2023-06-09 20:26 ` [PATCH v1 3/3] MdeModulePkg: Add Phase-Specific MemoryProtectionHobLib Implementations Taylor Beebe
  2 siblings, 0 replies; 4+ messages in thread
From: Taylor Beebe @ 2023-06-09 20:25 UTC (permalink / raw)
  To: devel; +Cc: Taylor Beebe, Jian J Wang, Liming Gao, Dandan Bi

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


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

* [PATCH v1 2/3] MdeModulePkg: Add MemoryProtectionHobLib Definitions and NULL Libs
  2023-06-09 20:25 [PATCH v1 0/3] MdeModulePkg: Adding Dynamic Memory Protection Settings Libraries Taylor Beebe
  2023-06-09 20:25 ` [PATCH v1 1/3] MdeModulePkg: Add DXE and MM Memory Protection Settings HOB Definitions Taylor Beebe
@ 2023-06-09 20:26 ` Taylor Beebe
  2023-06-09 20:26 ` [PATCH v1 3/3] MdeModulePkg: Add Phase-Specific MemoryProtectionHobLib Implementations Taylor Beebe
  2 siblings, 0 replies; 4+ messages in thread
From: Taylor Beebe @ 2023-06-09 20:26 UTC (permalink / raw)
  To: devel; +Cc: Taylor Beebe, Jian J Wang, Liming Gao, Dandan Bi

DxeMemoryProtectionHobLib and MmMemoryProtectionHobLib will fetch
the memory protection settings HOB entry for their respective phase,
validate the settings, and populate a global for access.

Memory protection settings are currently dictated via
FixedAtBuild PCDs where the settings needed to be masked.
A future patch series will replace instances of checking the
PCDs with checks to the memory protection globals populated by
MemoryProtectionHobLib.

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/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.c   | 33 ++++++++++++++++++
 MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.c    | 33 ++++++++++++++++++
 MdeModulePkg/Include/Library/DxeMemoryProtectionHobLib.h                          | 36 ++++++++++++++++++++
 MdeModulePkg/Include/Library/MmMemoryProtectionHobLib.h                           | 36 ++++++++++++++++++++
 MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf | 25 ++++++++++++++
 MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf  | 26 ++++++++++++++
 MdeModulePkg/MdeModulePkg.dec                                                     |  8 +++++
 MdeModulePkg/MdeModulePkg.dsc                                                     |  8 +++++
 8 files changed, 205 insertions(+)

diff --git a/MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.c b/MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.c
new file mode 100644
index 000000000000..4f0191d04974
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.c
@@ -0,0 +1,33 @@
+/** @file
+Library defines the gDxeMps global
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/DxeMemoryProtectionHobLib.h>
+
+// According to the C Specification, a global variable
+// which is uninitialized will be zero. The net effect
+// is memory protections will be OFF.
+DXE_MEMORY_PROTECTION_SETTINGS  gDxeMps;
+
+/**
+  Gets the input EFI_MEMORY_TYPE from the input DXE_HEAP_GUARD_MEMORY_TYPES bitfield
+
+  @param[in]  MemoryType            Memory type to check.
+  @param[in]  HeapGuardMemoryType   DXE_HEAP_GUARD_MEMORY_TYPES bitfield
+
+  @return TRUE  The given EFI_MEMORY_TYPE is TRUE in the given DXE_HEAP_GUARD_MEMORY_TYPES
+  @return FALSE The given EFI_MEMORY_TYPE is FALSE in the given DXE_HEAP_GUARD_MEMORY_TYPES
+**/
+BOOLEAN
+EFIAPI
+GetDxeMemoryTypeSettingFromBitfield (
+  IN EFI_MEMORY_TYPE              MemoryType,
+  IN DXE_HEAP_GUARD_MEMORY_TYPES  HeapGuardMemoryType
+  )
+{
+  return FALSE;
+}
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.c b/MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.c
new file mode 100644
index 000000000000..c62c9d772063
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.c
@@ -0,0 +1,33 @@
+/** @file
+Library defines the gMmMps global
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/MmMemoryProtectionHobLib.h>
+
+// According to the C Specification, a global variable
+// which is uninitialized will be zero. The net effect
+// is memory protections will be OFF.
+MM_MEMORY_PROTECTION_SETTINGS  gMmMps;
+
+/**
+  Gets the input EFI_MEMORY_TYPE from the input MM_HEAP_GUARD_MEMORY_TYPES bitfield
+
+  @param[in]  MemoryType            Memory type to check.
+  @param[in]  HeapGuardMemoryType   MM_HEAP_GUARD_MEMORY_TYPES bitfield
+
+  @return TRUE  The given EFI_MEMORY_TYPE is TRUE in the given MM_HEAP_GUARD_MEMORY_TYPES
+  @return FALSE The given EFI_MEMORY_TYPE is FALSE in the given MM_HEAP_GUARD_MEMORY_TYPES
+**/
+BOOLEAN
+EFIAPI
+GetMmMemoryTypeSettingFromBitfield (
+  IN EFI_MEMORY_TYPE             MemoryType,
+  IN MM_HEAP_GUARD_MEMORY_TYPES  HeapGuardMemoryType
+  )
+{
+  return FALSE;
+}
diff --git a/MdeModulePkg/Include/Library/DxeMemoryProtectionHobLib.h b/MdeModulePkg/Include/Library/DxeMemoryProtectionHobLib.h
new file mode 100644
index 000000000000..4f49a00a8683
--- /dev/null
+++ b/MdeModulePkg/Include/Library/DxeMemoryProtectionHobLib.h
@@ -0,0 +1,36 @@
+/** @file
+
+Library for controlling hob-backed memory protection settings
+
+Copyright (C) Microsoft Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef DXE_MEMORY_PROTECTION_HOB_HELPER_LIB_H_
+#define DXE_MEMORY_PROTECTION_HOB_HELPER_LIB_H_
+
+#include <Guid/DxeMemoryProtectionSettings.h>
+
+//
+//  The global used to access current Memory Protection Settings
+//
+extern DXE_MEMORY_PROTECTION_SETTINGS  gDxeMps;
+
+/**
+  Gets the input EFI_MEMORY_TYPE from the input DXE_HEAP_GUARD_MEMORY_TYPES bitfield
+
+  @param[in]  MemoryType            Memory type to check.
+  @param[in]  HeapGuardMemoryType   DXE_HEAP_GUARD_MEMORY_TYPES bitfield
+
+  @return TRUE  The given EFI_MEMORY_TYPE is TRUE in the given DXE_HEAP_GUARD_MEMORY_TYPES
+  @return FALSE The given EFI_MEMORY_TYPE is FALSE in the given DXE_HEAP_GUARD_MEMORY_TYPES
+**/
+BOOLEAN
+EFIAPI
+GetDxeMemoryTypeSettingFromBitfield (
+  IN EFI_MEMORY_TYPE              MemoryType,
+  IN DXE_HEAP_GUARD_MEMORY_TYPES  HeapGuardMemoryType
+  );
+
+#endif
diff --git a/MdeModulePkg/Include/Library/MmMemoryProtectionHobLib.h b/MdeModulePkg/Include/Library/MmMemoryProtectionHobLib.h
new file mode 100644
index 000000000000..efeaa9fd55aa
--- /dev/null
+++ b/MdeModulePkg/Include/Library/MmMemoryProtectionHobLib.h
@@ -0,0 +1,36 @@
+/** @file
+
+Library for controlling hob-backed memory protection settings
+
+Copyright (C) Microsoft Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_MEMORY_PROTECTION_HOB_HELPER_LIB_H_
+#define MM_MEMORY_PROTECTION_HOB_HELPER_LIB_H_
+
+#include <Guid/MmMemoryProtectionSettings.h>
+
+//
+//  The global used to access current Memory Protection Settings
+//
+extern MM_MEMORY_PROTECTION_SETTINGS  gMmMps;
+
+/**
+  Gets the input EFI_MEMORY_TYPE from the input MM_HEAP_GUARD_MEMORY_TYPES bitfield
+
+  @param[in]  MemoryType            Memory type to check.
+  @param[in]  HeapGuardMemoryType   MM_HEAP_GUARD_MEMORY_TYPES bitfield
+
+  @return TRUE  The given EFI_MEMORY_TYPE is TRUE in the given MM_HEAP_GUARD_MEMORY_TYPES
+  @return FALSE The given EFI_MEMORY_TYPE is FALSE in the given MM_HEAP_GUARD_MEMORY_TYPES
+**/
+BOOLEAN
+EFIAPI
+GetMmMemoryTypeSettingFromBitfield (
+  IN EFI_MEMORY_TYPE             MemoryType,
+  IN MM_HEAP_GUARD_MEMORY_TYPES  HeapGuardMemoryType
+  );
+
+#endif
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf b/MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
new file mode 100644
index 000000000000..6a3166a23b46
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
@@ -0,0 +1,25 @@
+## @file
+# NULL library which defines gDxeMps
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = DxeMemoryProtectionHobLibNull
+  FILE_GUID                      = a35c1dc1-0769-421b-a8bc-9db69fae4334
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = DxeMemoryProtectionHobLib
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  DxeMemoryProtectionHobLibNull.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf b/MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf
new file mode 100644
index 000000000000..61f50921ee04
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf
@@ -0,0 +1,26 @@
+## @file
+# NULL library which defines gMmMps
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MmMemoryProtectionHobLibNull
+  FILE_GUID                      = 4e3f6fd9-4ab5-4911-b80b-009d3338b4b2
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MmMemoryProtectionHobLib
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  MmMemoryProtectionHobLibNull.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 89001f217ed1..50dae9180d2b 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -164,6 +164,14 @@ [LibraryClasses]
   #
   VariableFlashInfoLib|Include/Library/VariableFlashInfoLib.h
 
+  ## @libraryclass Provides a way to toggle DXE memory protection settings
+  #
+  DxeMemoryProtectionHobLib|Include/Library/DxeMemoryProtectionHobLib.h
+
+  ## @libraryclass Provides a way to toggle SMM memory protection settings
+  #
+  MmMemoryProtectionHobLib|Include/Library/MmMemoryProtectionHobLib.h
+
 [Guids]
   ## MdeModule package token space guid
   # Include/Guid/MdeModulePkgTokenSpace.h
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index 5b1f50e9c084..ab6848dc934b 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -107,6 +107,12 @@ [LibraryClasses]
   VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf
   IpmiCommandLib|MdeModulePkg/Library/BaseIpmiCommandLibNull/BaseIpmiCommandLibNull.inf
 
+[LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_CORE, LibraryClasses.common.UEFI_APPLICATION]
+  DxeMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
+
+[LibraryClasses.common.SMM_CORE, LibraryClasses.common.DXE_SMM_DRIVER, LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.MM_STANDALONE]
+  MmMemoryProtectionHobLib|MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf
+
 [LibraryClasses.EBC.PEIM]
   IoLib|MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf
 
@@ -231,6 +237,8 @@ [Components]
   MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
   MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
   MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+  MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
+  MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf
   MdeModulePkg/Library/PciHostBridgeLibNull/PciHostBridgeLibNull.inf
   MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf
   MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
-- 
2.36.1.windows.1


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

* [PATCH v1 3/3] MdeModulePkg: Add Phase-Specific MemoryProtectionHobLib Implementations
  2023-06-09 20:25 [PATCH v1 0/3] MdeModulePkg: Adding Dynamic Memory Protection Settings Libraries Taylor Beebe
  2023-06-09 20:25 ` [PATCH v1 1/3] MdeModulePkg: Add DXE and MM Memory Protection Settings HOB Definitions Taylor Beebe
  2023-06-09 20:26 ` [PATCH v1 2/3] MdeModulePkg: Add MemoryProtectionHobLib Definitions and NULL Libs Taylor Beebe
@ 2023-06-09 20:26 ` Taylor Beebe
  2 siblings, 0 replies; 4+ messages in thread
From: Taylor Beebe @ 2023-06-09 20:26 UTC (permalink / raw)
  To: devel; +Cc: Taylor Beebe, Jian J Wang, Liming Gao, Dandan Bi

Add DXE, SMM, and STANDALONE MM implementations of the
MemoryProtectionHobLib.

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/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.c            | 182 ++++++++++++++++++++
 MdeModulePkg/Library/MemoryProtectionHobLib/MmCommonMemoryProtectionHobLib.c       | 139 +++++++++++++++
 MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.c            |  37 ++++
 MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.c   |  37 ++++
 MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf          |  34 ++++
 MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf          |  35 ++++
 MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf |  36 ++++
 MdeModulePkg/MdeModulePkg.dsc                                                      |   3 +
 8 files changed, 503 insertions(+)

diff --git a/MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.c b/MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.c
new file mode 100644
index 000000000000..fa6137f90eba
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.c
@@ -0,0 +1,182 @@
+/** @file
+Library fills out gDxeMps global
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Pi/PiMultiPhase.h>
+#include <Uefi/UefiMultiPhase.h>
+
+#include <Library/DxeMemoryProtectionHobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+
+DXE_MEMORY_PROTECTION_SETTINGS  gDxeMps;
+
+/**
+  Gets the input EFI_MEMORY_TYPE from the input DXE_HEAP_GUARD_MEMORY_TYPES bitfield
+
+  @param[in]  MemoryType            Memory type to check.
+  @param[in]  HeapGuardMemoryType   DXE_HEAP_GUARD_MEMORY_TYPES bitfield
+
+  @return TRUE  The given EFI_MEMORY_TYPE is TRUE in the given DXE_HEAP_GUARD_MEMORY_TYPES
+  @return FALSE The given EFI_MEMORY_TYPE is FALSE in the given DXE_HEAP_GUARD_MEMORY_TYPES
+**/
+BOOLEAN
+EFIAPI
+GetDxeMemoryTypeSettingFromBitfield (
+  IN EFI_MEMORY_TYPE              MemoryType,
+  IN DXE_HEAP_GUARD_MEMORY_TYPES  HeapGuardMemoryType
+  )
+{
+  switch (MemoryType) {
+    case EfiReservedMemoryType:
+      return HeapGuardMemoryType.Fields.EfiReservedMemoryType;
+    case EfiLoaderCode:
+      return HeapGuardMemoryType.Fields.EfiLoaderCode;
+    case EfiLoaderData:
+      return HeapGuardMemoryType.Fields.EfiLoaderData;
+    case EfiBootServicesCode:
+      return HeapGuardMemoryType.Fields.EfiBootServicesCode;
+    case EfiBootServicesData:
+      return HeapGuardMemoryType.Fields.EfiBootServicesData;
+    case EfiRuntimeServicesCode:
+      return HeapGuardMemoryType.Fields.EfiRuntimeServicesCode;
+    case EfiRuntimeServicesData:
+      return HeapGuardMemoryType.Fields.EfiRuntimeServicesData;
+    case EfiConventionalMemory:
+      return HeapGuardMemoryType.Fields.EfiConventionalMemory;
+    case EfiUnusableMemory:
+      return HeapGuardMemoryType.Fields.EfiUnusableMemory;
+    case EfiACPIReclaimMemory:
+      return HeapGuardMemoryType.Fields.EfiACPIReclaimMemory;
+    case EfiACPIMemoryNVS:
+      return HeapGuardMemoryType.Fields.EfiACPIMemoryNVS;
+    case EfiMemoryMappedIO:
+      return HeapGuardMemoryType.Fields.EfiMemoryMappedIO;
+    case EfiMemoryMappedIOPortSpace:
+      return HeapGuardMemoryType.Fields.EfiMemoryMappedIOPortSpace;
+    case EfiPalCode:
+      return HeapGuardMemoryType.Fields.EfiPalCode;
+    case EfiPersistentMemory:
+      return HeapGuardMemoryType.Fields.EfiPersistentMemory;
+    default:
+      return FALSE;
+  }
+}
+
+/**
+  This function checks the memory protection settings and provides warnings of conflicts and/or
+  potentially unforseen consequences from the settings. This logic will only ever turn off
+  protections to create consistency, never turn others on.
+**/
+VOID
+DxeMemoryProtectionSettingsConsistencyCheck (
+  VOID
+  )
+{
+  if ((gDxeMps.HeapGuardPolicy.Fields.PoolGuardEnabled || gDxeMps.HeapGuardPolicy.Fields.PageGuardEnabled) &&
+      gDxeMps.HeapGuardPolicy.Fields.FreedMemoryGuardEnabled)
+  {
+    DEBUG ((
+      DEBUG_WARN,
+      "%a: - HeapGuardPolicy.FreedMemoryGuardEnabled and "
+      "UEFI HeapGuardPolicy.PoolGuardEnabled/HeapGuardPolicy.PageGuardEnabled "
+      "cannot be active at the same time. Setting all three to ZERO in "
+      "the memory protection settings global.\n",
+      __func__
+      ));
+    ASSERT (
+      !(gDxeMps.HeapGuardPolicy.Fields.FreedMemoryGuardEnabled &&
+        (gDxeMps.HeapGuardPolicy.Fields.PoolGuardEnabled || gDxeMps.HeapGuardPolicy.Fields.PageGuardEnabled))
+      );
+    gDxeMps.HeapGuardPolicy.Fields.PoolGuardEnabled        = 0;
+    gDxeMps.HeapGuardPolicy.Fields.PageGuardEnabled        = 0;
+    gDxeMps.HeapGuardPolicy.Fields.FreedMemoryGuardEnabled = 0;
+  }
+
+  if (gDxeMps.HeapGuardPoolType.Data &&
+      (!(gDxeMps.HeapGuardPolicy.Fields.PoolGuardEnabled)))
+  {
+    DEBUG ((
+      DEBUG_WARN,
+      "%a: - Heap Guard Pool protections are active, "
+      "but neither HeapGuardPolicy.PoolGuardEnabled nor "
+      "HeapGuardPolicy.PoolGuardEnabled are active.\n",
+      __func__
+      ));
+  }
+
+  if (gDxeMps.HeapGuardPageType.Data &&
+      (!(gDxeMps.HeapGuardPolicy.Fields.PageGuardEnabled)))
+  {
+    DEBUG ((
+      DEBUG_WARN,
+      "%a: - Heap Guard Page protections are active, "
+      "but neither HeapGuardPolicy.PageGuardEnabled nor "
+      "HeapGuardPolicy.PageGuardEnabled are active.\n",
+      __func__
+      ));
+  }
+
+  if (gDxeMps.NxProtectionPolicy.Fields.EfiBootServicesData != gDxeMps.NxProtectionPolicy.Fields.EfiConventionalMemory) {
+    DEBUG ((
+      DEBUG_WARN,
+      "%a: - NxProtectionPolicy.EfiBootServicesData "
+      "and NxProtectionPolicy.EfiConventionalMemory must have the same value. "
+      "Setting both to ZERO in the memory protection settings global.\n",
+      __func__
+      ));
+    ASSERT (
+      gDxeMps.NxProtectionPolicy.Fields.EfiBootServicesData ==
+      gDxeMps.NxProtectionPolicy.Fields.EfiConventionalMemory
+      );
+    gDxeMps.NxProtectionPolicy.Fields.EfiBootServicesData   = 0;
+    gDxeMps.NxProtectionPolicy.Fields.EfiConventionalMemory = 0;
+  }
+}
+
+/**
+  Populates gDxeMps global with the data present in the HOB. If the HOB entry does not exist,
+  this constructor will zero the memory protection settings.
+
+  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.
+  @param[in]  SystemTable   A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+DxeMemoryProtectionHobLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  VOID  *Ptr;
+
+  Ptr = GetFirstGuidHob (&gDxeMemoryProtectionSettingsGuid);
+
+  //
+  // Cache the Memory Protection Settings HOB entry
+  //
+  if (Ptr != NULL) {
+    if (*((UINT8 *)GET_GUID_HOB_DATA (Ptr)) != (UINT8)DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "%a: - Version number of the Memory Protection Settings HOB is invalid!\n",
+        __func__
+        ));
+      ASSERT (*((UINT8 *)GET_GUID_HOB_DATA (Ptr)) == (UINT8)DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION);
+      ZeroMem (&gDxeMps, sizeof (gDxeMps));
+      return EFI_SUCCESS;
+    }
+
+    CopyMem (&gDxeMps, GET_GUID_HOB_DATA (Ptr), sizeof (DXE_MEMORY_PROTECTION_SETTINGS));
+    DxeMemoryProtectionSettingsConsistencyCheck ();
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLib/MmCommonMemoryProtectionHobLib.c b/MdeModulePkg/Library/MemoryProtectionHobLib/MmCommonMemoryProtectionHobLib.c
new file mode 100644
index 000000000000..c546a943a515
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLib/MmCommonMemoryProtectionHobLib.c
@@ -0,0 +1,139 @@
+/** @file
+Library fills out gMmMps global
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Pi/PiMultiPhase.h>
+#include <Uefi/UefiMultiPhase.h>
+
+#include <Library/MmMemoryProtectionHobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/BaseMemoryLib.h>
+
+MM_MEMORY_PROTECTION_SETTINGS  gMmMps;
+
+/**
+  Gets the input EFI_MEMORY_TYPE from the input MM_HEAP_GUARD_MEMORY_TYPES bitfield
+
+  @param[in]  MemoryType            Memory type to check.
+  @param[in]  HeapGuardMemoryType   MM_HEAP_GUARD_MEMORY_TYPES bitfield
+
+  @return TRUE  The given EFI_MEMORY_TYPE is TRUE in the given MM_HEAP_GUARD_MEMORY_TYPES
+  @return FALSE The given EFI_MEMORY_TYPE is FALSE in the given MM_HEAP_GUARD_MEMORY_TYPES
+**/
+BOOLEAN
+EFIAPI
+GetMmMemoryTypeSettingFromBitfield (
+  IN EFI_MEMORY_TYPE             MemoryType,
+  IN MM_HEAP_GUARD_MEMORY_TYPES  HeapGuardMemoryType
+  )
+{
+  switch (MemoryType) {
+    case EfiReservedMemoryType:
+      return HeapGuardMemoryType.Fields.EfiReservedMemoryType;
+    case EfiLoaderCode:
+      return HeapGuardMemoryType.Fields.EfiLoaderCode;
+    case EfiLoaderData:
+      return HeapGuardMemoryType.Fields.EfiLoaderData;
+    case EfiBootServicesCode:
+      return HeapGuardMemoryType.Fields.EfiBootServicesCode;
+    case EfiBootServicesData:
+      return HeapGuardMemoryType.Fields.EfiBootServicesData;
+    case EfiRuntimeServicesCode:
+      return HeapGuardMemoryType.Fields.EfiRuntimeServicesCode;
+    case EfiRuntimeServicesData:
+      return HeapGuardMemoryType.Fields.EfiRuntimeServicesData;
+    case EfiConventionalMemory:
+      return HeapGuardMemoryType.Fields.EfiConventionalMemory;
+    case EfiUnusableMemory:
+      return HeapGuardMemoryType.Fields.EfiUnusableMemory;
+    case EfiACPIReclaimMemory:
+      return HeapGuardMemoryType.Fields.EfiACPIReclaimMemory;
+    case EfiACPIMemoryNVS:
+      return HeapGuardMemoryType.Fields.EfiACPIMemoryNVS;
+    case EfiMemoryMappedIO:
+      return HeapGuardMemoryType.Fields.EfiMemoryMappedIO;
+    case EfiMemoryMappedIOPortSpace:
+      return HeapGuardMemoryType.Fields.EfiMemoryMappedIOPortSpace;
+    case EfiPalCode:
+      return HeapGuardMemoryType.Fields.EfiPalCode;
+    case EfiPersistentMemory:
+      return HeapGuardMemoryType.Fields.EfiPersistentMemory;
+    default:
+      return FALSE;
+  }
+}
+
+/**
+  This function checks the memory protection settings and provides warnings of conflicts and/or
+  potentially unforseen consequences from the settings. This logic will only ever turn off
+  protections to create consistency, never turn others on.
+**/
+VOID
+MmMemoryProtectionSettingsConsistencyCheck (
+  VOID
+  )
+{
+  if (gMmMps.HeapGuardPoolType.Data &&
+      (!(gMmMps.HeapGuardPolicy.Fields.PoolGuardEnabled)))
+  {
+    DEBUG ((
+      DEBUG_WARN,
+      "%a: - Bits set in gMmMps.HeapGuardPoolType, but gMmMps.HeapGuardPolicy.Fields.PoolGuardEnabled is inactive. "
+      "No pool guards will be set.\n",
+      __func__
+      ));
+  }
+
+  if (gMmMps.HeapGuardPageType.Data &&
+      (!(gMmMps.HeapGuardPolicy.Fields.PageGuardEnabled)))
+  {
+    DEBUG ((
+      DEBUG_WARN,
+      "%a: - Bits are set in gMmMps.HeapGuardPageType, but gMmMps.HeapGuardPolicy.Fields.PageGuardEnabled is inactive. "
+      "No page guards will be set.\n",
+      __func__
+      ));
+  }
+}
+
+/**
+  Abstraction layer for library constructor of Standalone MM and SMM instances.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+MmMemoryProtectionHobLibConstructorCommon (
+  VOID
+  )
+{
+  VOID  *Ptr;
+
+  Ptr = GetFirstGuidHob (&gMmMemoryProtectionSettingsGuid);
+
+  //
+  // Cache the Memory Protection Settings HOB entry
+  //
+  if (Ptr != NULL) {
+    if (*((UINT8 *)GET_GUID_HOB_DATA (Ptr)) != (UINT8)MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "%a: - Version number of the Memory Protection Settings HOB is invalid!\n",
+        __func__
+        ));
+      ASSERT (*((UINT8 *)GET_GUID_HOB_DATA (Ptr)) == (UINT8)MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION);
+      ZeroMem (&gMmMps, sizeof (gMmMps));
+      return EFI_SUCCESS;
+    }
+
+    CopyMem (&gMmMps, GET_GUID_HOB_DATA (Ptr), sizeof (MM_MEMORY_PROTECTION_SETTINGS));
+    MmMemoryProtectionSettingsConsistencyCheck ();
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.c b/MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.c
new file mode 100644
index 000000000000..fffc90a7215c
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.c
@@ -0,0 +1,37 @@
+/** @file
+Library fills out gMmMps global
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiSmm.h>
+
+/**
+  Abstraction layer for library constructor of Standalone MM and SMM instances.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+MmMemoryProtectionHobLibConstructorCommon (
+  VOID
+  );
+
+/**
+  Library constructor of SMM instance.
+
+  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.
+  @param[in]  SystemTable   A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+SmmMemoryProtectionHobLibConstructor (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  return MmMemoryProtectionHobLibConstructorCommon ();
+}
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.c b/MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.c
new file mode 100644
index 000000000000..3fd8b9f2593d
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.c
@@ -0,0 +1,37 @@
+/** @file
+Library fills out gMmMps global
+
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <PiMm.h>
+
+/**
+  Abstraction layer for library constructor of Standalone MM and SMM instances.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+MmMemoryProtectionHobLibConstructorCommon (
+  VOID
+  );
+
+/**
+  Library constructor of Standalone MM instance.
+
+  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.
+  @param[in]  SystemTable   A pointer to the EFI MM System Table.
+
+  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.
+**/
+EFI_STATUS
+EFIAPI
+StandaloneMmMemoryProtectionHobLibConstructor (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_MM_SYSTEM_TABLE  *SystemTable
+  )
+{
+  return MmMemoryProtectionHobLibConstructorCommon ();
+}
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf b/MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf
new file mode 100644
index 000000000000..57ca55446b81
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf
@@ -0,0 +1,34 @@
+## @file
+# DXE library instance to support platform-specific global controls for all memory protections.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = DxeMemoryProtectionHobLib
+  FILE_GUID                      = f497f7de-b9ab-4b9f-807e-89778922542d
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = DxeMemoryProtectionHobLib|DXE_DRIVER DXE_CORE UEFI_APPLICATION UEFI_DRIVER
+  CONSTRUCTOR                    = DxeMemoryProtectionHobLibConstructor
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  DxeMemoryProtectionHobLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  HobLib
+  DebugLib
+  BaseMemoryLib
+
+[Guids]
+  gDxeMemoryProtectionSettingsGuid
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf b/MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf
new file mode 100644
index 000000000000..4651158bd405
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf
@@ -0,0 +1,35 @@
+## @file
+# SMM library instance to support platform-specific global controls for all memory protections.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmmMemoryProtectionHobLib
+  FILE_GUID                      = dc9666f4-917f-400d-8026-2b3beeeff195
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MmMemoryProtectionHobLib|SMM_CORE DXE_SMM_DRIVER
+  CONSTRUCTOR                    = SmmMemoryProtectionHobLibConstructor
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  MmCommonMemoryProtectionHobLib.c
+  SmmMemoryProtectionHobLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  HobLib
+  DebugLib
+  BaseMemoryLib
+
+[Guids]
+  gMmMemoryProtectionSettingsGuid
diff --git a/MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf b/MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf
new file mode 100644
index 000000000000..3cadb5ec6e9a
--- /dev/null
+++ b/MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf
@@ -0,0 +1,36 @@
+## @file
+# SMM library instance to support platform-specific global controls for all memory protections.
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = StandaloneMmMemoryProtectionHobLib
+  FILE_GUID                      = C0A0D9C4-A249-483A-86EA-D73146D397B3
+  MODULE_TYPE                    = MM_CORE_STANDALONE
+  PI_SPECIFICATION_VERSION       = 0x00010032
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MmMemoryProtectionHobLib|MM_CORE_STANDALONE MM_STANDALONE
+  CONSTRUCTOR                    = StandaloneMmMemoryProtectionHobLibConstructor
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  MmCommonMemoryProtectionHobLib.c
+  StandaloneMmMemoryProtectionHobLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  HobLib
+  DebugLib
+  BaseMemoryLib
+
+[Guids]
+  gMmMemoryProtectionSettingsGuid
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index ab6848dc934b..bad4318771f9 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -237,6 +237,9 @@ [Components]
   MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
   MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
   MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+  MdeModulePkg/Library/MemoryProtectionHobLib/DxeMemoryProtectionHobLib.inf
+  MdeModulePkg/Library/MemoryProtectionHobLib/SmmMemoryProtectionHobLib.inf
+  MdeModulePkg/Library/MemoryProtectionHobLib/StandaloneMmMemoryProtectionHobLib.inf
   MdeModulePkg/Library/MemoryProtectionHobLibNull/DxeMemoryProtectionHobLibNull.inf
   MdeModulePkg/Library/MemoryProtectionHobLibNull/MmMemoryProtectionHobLibNull.inf
   MdeModulePkg/Library/PciHostBridgeLibNull/PciHostBridgeLibNull.inf
-- 
2.36.1.windows.1


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

end of thread, other threads:[~2023-06-09 20:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-09 20:25 [PATCH v1 0/3] MdeModulePkg: Adding Dynamic Memory Protection Settings Libraries Taylor Beebe
2023-06-09 20:25 ` [PATCH v1 1/3] MdeModulePkg: Add DXE and MM Memory Protection Settings HOB Definitions Taylor Beebe
2023-06-09 20:26 ` [PATCH v1 2/3] MdeModulePkg: Add MemoryProtectionHobLib Definitions and NULL Libs Taylor Beebe
2023-06-09 20:26 ` [PATCH v1 3/3] MdeModulePkg: Add Phase-Specific MemoryProtectionHobLib Implementations Taylor Beebe

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