From: "Taylor Beebe" <t@taylorbeebe.com>
To: devel@edk2.groups.io
Cc: Jian J Wang <jian.j.wang@intel.com>,
Liming Gao <gaoliming@byosoft.com.cn>,
Dandan Bi <dandan.bi@intel.com>
Subject: [PATCH 01/14] MdeModulePkg: Add DXE and MM Memory Protection Settings Definitions
Date: Tue, 11 Jul 2023 16:52:38 -0700 [thread overview]
Message-ID: <90e3068695d8dc23c940e7f8ad00a7efc6d91bd6.1689101263.git.t@taylorbeebe.com> (raw)
In-Reply-To: <cover.1689101263.git.t@taylorbeebe.com>
From: Taylor Beebe <tabeebe@microsoft.com>
These headers provide settings definitions for memory protections,
settings profiles for easily enabling memory protections,
and the GUIDs used for producing the memory protection HOB.
The settings options are functionally 1:1 with the existing
PCD bitfield definitions. Instead of setting a fixed at build
PCD, memory protection settings will be created via a HOB
at runtime.
Signed-off-by: Taylor Beebe <t@taylorbeebe.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
---
.../Guid/DxeMemoryProtectionSettings.h | 413 ++++++++++++++++++
.../Include/Guid/MmMemoryProtectionSettings.h | 211 +++++++++
MdeModulePkg/MdeModulePkg.dec | 10 +
3 files changed, 634 insertions(+)
create mode 100644 MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h
create mode 100644 MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h
diff --git a/MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h b/MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h
new file mode 100644
index 0000000000..93144494d5
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/DxeMemoryProtectionSettings.h
@@ -0,0 +1,413 @@
+/** @file
+
+Defines memory protection settings guid and struct for DXE.
+
+Copyright (C) Microsoft Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef DXE_MEMORY_PROTECTION_SETTINGS_H_
+#define DXE_MEMORY_PROTECTION_SETTINGS_H_
+
+#include <Library/BaseMemoryLib.h>
+
+// Current iteration of DXE_MEMORY_PROTECTION_SETTINGS
+#define DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION 1
+
+#define OEM_RESERVED_MPS_MEMORY_TYPE EfiMaxMemoryType
+#define OS_RESERVED_MPS_MEMORY_TYPE (EfiMaxMemoryType + 1)
+#define MAX_DXE_MPS_MEMORY_TYPE (EfiMaxMemoryType + 2)
+#define DXE_MPS_MEMORY_TYPE_BUFFER_SIZE (MAX_DXE_MPS_MEMORY_TYPE * sizeof (BOOLEAN))
+
+typedef struct {
+ BOOLEAN Enabled : 1;
+ BOOLEAN DisableEndOfDxe : 1;
+ BOOLEAN NonstopModeEnabled : 1;
+} DXE_NULL_DETECTION_POLICY;
+
+typedef struct {
+ BOOLEAN ProtectImageFromUnknown : 1;
+ BOOLEAN ProtectImageFromFv : 1;
+} DXE_IMAGE_PROTECTION_POLICY;
+
+typedef struct {
+ BOOLEAN PageGuardEnabled : 1;
+ BOOLEAN PoolGuardEnabled : 1;
+ BOOLEAN FreedMemoryGuardEnabled : 1;
+ BOOLEAN NonstopModeEnabled : 1;
+ BOOLEAN GuardAlignedToTail : 1;
+} DXE_HEAP_GUARD_POLICY;
+
+typedef struct {
+ BOOLEAN EnabledForType[MAX_DXE_MPS_MEMORY_TYPE];
+} DXE_MPS_MEMORY_TYPES;
+
+typedef UINT8 DXE_MEMORY_PROTECTION_SETTINGS_VERSION;
+
+//
+// Memory Protection Settings struct
+//
+typedef struct {
+ // The current version of the structure definition. This is used to ensure there isn't a
+ // definition mismatch if modules have differing iterations of this header. When creating
+ // this struct, use the DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION macro.
+ DXE_MEMORY_PROTECTION_SETTINGS_VERSION StructVersion;
+
+ // If enabled, the page at the top of the stack will be invalidated to catch stack overflow.
+ BOOLEAN CpuStackGuardEnabled;
+
+ // If enabled, the stack will be marked non-executable.
+ BOOLEAN StackExecutionProtectionEnabled;
+
+ // If enabled, accessing the NULL address in UEFI will be caught by marking
+ // the NULL page as not present.
+ // .NullDetectionEnabled : Enable NULL pointer detection.
+ // .DisableEndOfDxe : Disable NULL pointer detection just after EndOfDxe.
+ // This is a workaround for those unsolvable NULL access issues in
+ // OptionROM, boot loader, etc. It can also help to avoid unnecessary
+ // exception caused by legacy memory (0-4095) access after EndOfDxe,
+ // such as Windows 7 boot on Qemu.
+ // .NonstopModeEnabled : If enabled the debug flag will be raised when a fault occurs
+ // to break into debugger.
+ DXE_NULL_DETECTION_POLICY NullPointerDetection;
+
+ // Set image protection policy.
+ //
+ // .ProtectImageFromUnknown : If set, images from unknown devices will be protected by
+ // DxeCore if they are aligned. The code section becomes
+ // read-only, and the data section becomes non-executable.
+ // .ProtectImageFromFv : If set, images from firmware volumes will be protected by
+ // DxeCore if they are aligned. The code section becomes
+ // read-only, and the data section becomes non-executable.
+ DXE_IMAGE_PROTECTION_POLICY ImageProtection;
+
+ // If a bit is set, memory regions of the associated type will be mapped non-executable.
+ //
+ // The execution protection setting for EfiBootServicesData and EfiConventionalMemory must
+ // be the same.
+ DXE_MPS_MEMORY_TYPES ExecutionProtection;
+
+ // Configures general heap guard behavior.
+ //
+ // .PageGuardEnabled : Enable page guard.
+ // .PoolGuardEnabled : Enable pool guard.
+ // .FreedMemoryGuardEnabled : Enable freed-memory guard (Use-After-Free memory detection).
+ // .NonstopModeEnabled : If enabled the debug flag will be raised when a fault occurs
+ // to break into debugger.
+ // .GuardAlignedToTail : TRUE if the pool is aligned to tail guard page. If FALSE, the
+ // pool is aligned to head guard page.
+ //
+ // Note:
+ // a) Due to the limit of pool memory implementation and the alignment
+ // requirement of UEFI spec, HeapGuard.GuardAlignedToTail is a try-best
+ // setting which cannot guarantee that the returned pool is exactly
+ // adjacent to head or tail guard page.
+ // b) Freed-memory guard and pool/page guard cannot be enabled
+ // at the same time.
+ DXE_HEAP_GUARD_POLICY HeapGuard;
+
+ // Indicates which type allocation need guard page.
+ //
+ // If bit is set, a head guard page and a tail guard page will be added just
+ // before and after corresponding type of pages which the allocated pool occupies,
+ // if there's enough free memory for all of them.
+ //
+ // These settings are only valid if HeapGuard.PoolGuardEnabled is TRUE.
+ DXE_MPS_MEMORY_TYPES PoolGuard;
+
+ // Indicates which type allocation need guard page.
+ //
+ // If a bit is set, a head guard page and a tail guard page will be added just
+ // before and after corresponding type of pages allocated if there's enough
+ // free pages for all of them.
+ //
+ // These settings are only valid if HeapGuard.PageGuardEnabled is TRUE.
+ DXE_MPS_MEMORY_TYPES PageGuard;
+} DXE_MEMORY_PROTECTION_SETTINGS;
+
+#define DXE_MPS_IS_STRUCT_VALID(DxeMpsPtr) \
+ (((DXE_MEMORY_PROTECTION_SETTINGS *)DxeMpsPtr)->StructVersion == DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION)
+
+#define DXE_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(MpsMemoryTypesPtr) \
+ (!IsZeroBuffer (&((DXE_MPS_MEMORY_TYPES *)MpsMemoryTypesPtr)->EnabledForType, DXE_MPS_MEMORY_TYPE_BUFFER_SIZE))
+
+#define DXE_MPS_IS_IMAGE_PROTECTION_ENABLED(DxeMpsPtr) \
+ (((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->ImageProtection.ProtectImageFromFv || \
+ ((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->ImageProtection.ProtectImageFromUnknown)
+
+#define DXE_MPS_IS_EXECUTION_PROTECTION_ENABLED(DxeMpsPtr) \
+ DXE_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->ExecutionProtection)
+
+#define DXE_MPS_ARE_PAGE_GUARDS_ENABLED(DxeMpsPtr) \
+ (((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->HeapGuard.PageGuardEnabled && \
+ DXE_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->PageGuard))
+
+#define DXE_MPS_ARE_POOL_GUARDS_ENABLED(DxeMpsPtr) \
+ (((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->HeapGuard.PoolGuardEnabled && \
+ DXE_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->PoolGuard))
+
+#define DXE_MPS_IS_MEMORY_PROTECTION_ACTIVE(DxeMpsPtr) \
+ (DXE_MPS_IS_STRUCT_VALID(DxeMpsPtr) && \
+ (((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->CpuStackGuardEnabled || \
+ ((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->StackExecutionProtectionEnabled || \
+ ((DXE_MEMORY_PROTECTION_SETTINGS*)DxeMpsPtr)->NullPointerDetection.Enabled || \
+ DXE_MPS_IS_IMAGE_PROTECTION_ENABLED(DxeMpsPtr) || \
+ DXE_MPS_IS_EXECUTION_PROTECTION_ENABLED(DxeMpsPtr) || \
+ DXE_MPS_ARE_PAGE_GUARDS_ENABLED(DxeMpsPtr) || \
+ DXE_MPS_ARE_POOL_GUARDS_ENABLED(DxeMpsPtr)) \
+ )
+
+#define HOB_DXE_MEMORY_PROTECTION_SETTINGS_GUID \
+ { \
+ { 0x9ABFD639, 0xD1D0, 0x4EFF, { 0xBD, 0xB6, 0x7E, 0xC4, 0x19, 0x0D, 0x17, 0xD5 } } \
+ }
+
+extern GUID gDxeMemoryProtectionSettingsGuid;
+
+//
+// A memory profile with strict settings ideal for development scenarios.
+//
+#define DXE_MEMORY_PROTECTION_SETTINGS_DEBUG { \
+ DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION, \
+ TRUE, /* Stack Guard */ \
+ TRUE, /* Stack Execution Protection */ \
+ { /* NULL Pointer Detection */ \
+ .Enabled = TRUE, \
+ .DisableEndOfDxe = FALSE, \
+ .NonstopModeEnabled = TRUE \
+ }, \
+ { /* Image Protection */ \
+ .ProtectImageFromUnknown = TRUE, \
+ .ProtectImageFromFv = TRUE \
+ }, \
+ { /* Execution Protection */ \
+ .EnabledForType = { \
+ [EfiReservedMemoryType] = TRUE, \
+ [EfiLoaderCode] = FALSE, \
+ [EfiLoaderData] = TRUE, \
+ [EfiBootServicesCode] = FALSE, \
+ [EfiBootServicesData] = TRUE, \
+ [EfiRuntimeServicesCode] = FALSE, \
+ [EfiRuntimeServicesData] = TRUE, \
+ [EfiConventionalMemory] = TRUE, \
+ [EfiUnusableMemory] = TRUE, \
+ [EfiACPIReclaimMemory] = TRUE, \
+ [EfiACPIMemoryNVS] = TRUE, \
+ [EfiMemoryMappedIO] = TRUE, \
+ [EfiMemoryMappedIOPortSpace] = TRUE, \
+ [EfiPalCode] = TRUE, \
+ [EfiPersistentMemory] = FALSE, \
+ [EfiUnacceptedMemoryType] = TRUE, \
+ [OEM_RESERVED_MPS_MEMORY_TYPE] = TRUE, \
+ [OS_RESERVED_MPS_MEMORY_TYPE] = TRUE \
+ } \
+ }, \
+ { /* Heap Guard */ \
+ .PageGuardEnabled = TRUE, \
+ .PoolGuardEnabled = TRUE, \
+ .FreedMemoryGuardEnabled = FALSE, \
+ .NonstopModeEnabled = TRUE, \
+ .GuardAlignedToTail = FALSE \
+ }, \
+ { /* Pool Guard */ \
+ .EnabledForType = { \
+ [EfiReservedMemoryType] = TRUE, \
+ [EfiLoaderCode] = TRUE, \
+ [EfiLoaderData] = TRUE, \
+ [EfiBootServicesCode] = TRUE, \
+ [EfiBootServicesData] = TRUE, \
+ [EfiRuntimeServicesCode] = TRUE, \
+ [EfiRuntimeServicesData] = TRUE, \
+ [EfiConventionalMemory] = FALSE, \
+ [EfiUnusableMemory] = TRUE, \
+ [EfiACPIReclaimMemory] = TRUE, \
+ [EfiACPIMemoryNVS] = TRUE, \
+ [EfiMemoryMappedIO] = TRUE, \
+ [EfiMemoryMappedIOPortSpace] = TRUE, \
+ [EfiPalCode] = TRUE, \
+ [EfiPersistentMemory] = FALSE, \
+ [EfiUnacceptedMemoryType] = TRUE, \
+ [OEM_RESERVED_MPS_MEMORY_TYPE] = TRUE, \
+ [OS_RESERVED_MPS_MEMORY_TYPE] = TRUE \
+ } \
+ }, \
+ { /* Page Guard */ \
+ .EnabledForType = { \
+ [EfiReservedMemoryType] = TRUE, \
+ [EfiLoaderCode] = TRUE, \
+ [EfiLoaderData] = TRUE, \
+ [EfiBootServicesCode] = TRUE, \
+ [EfiBootServicesData] = TRUE, \
+ [EfiRuntimeServicesCode] = TRUE, \
+ [EfiRuntimeServicesData] = TRUE, \
+ [EfiConventionalMemory] = FALSE, \
+ [EfiUnusableMemory] = TRUE, \
+ [EfiACPIReclaimMemory] = TRUE, \
+ [EfiACPIMemoryNVS] = TRUE, \
+ [EfiMemoryMappedIO] = TRUE, \
+ [EfiMemoryMappedIOPortSpace] = TRUE, \
+ [EfiPalCode] = TRUE, \
+ [EfiPersistentMemory] = FALSE, \
+ [EfiUnacceptedMemoryType] = TRUE, \
+ [OEM_RESERVED_MPS_MEMORY_TYPE] = TRUE, \
+ [OS_RESERVED_MPS_MEMORY_TYPE] = TRUE \
+ } \
+ } \
+ };
+
+//
+// A memory profile recommended for production. Compared to the debug
+// settings, this profile removes the pool guards and uses page guards
+// for fewer memory types.
+//
+#define DXE_MEMORY_PROTECTION_SETTINGS_PROD_MODE \
+ { \
+ DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION, \
+ TRUE, /* Stack Guard */ \
+ TRUE, /* Stack Execution Protection */ \
+ { /* NULL Pointer Detection */ \
+ .Enabled = TRUE, \
+ .DisableEndOfDxe = FALSE, \
+ .NonstopModeEnabled = FALSE \
+ }, \
+ { /* Image Protection */ \
+ .ProtectImageFromUnknown = FALSE, \
+ .ProtectImageFromFv = TRUE \
+ }, \
+ { /* Execution Protection */ \
+ .EnabledForType = { \
+ [EfiReservedMemoryType] = TRUE, \
+ [EfiLoaderCode] = FALSE, \
+ [EfiLoaderData] = TRUE, \
+ [EfiBootServicesCode] = FALSE, \
+ [EfiBootServicesData] = TRUE, \
+ [EfiRuntimeServicesCode] = FALSE, \
+ [EfiRuntimeServicesData] = TRUE, \
+ [EfiConventionalMemory] = TRUE, \
+ [EfiUnusableMemory] = TRUE, \
+ [EfiACPIReclaimMemory] = TRUE, \
+ [EfiACPIMemoryNVS] = TRUE, \
+ [EfiMemoryMappedIO] = TRUE, \
+ [EfiMemoryMappedIOPortSpace] = TRUE, \
+ [EfiPalCode] = TRUE, \
+ [EfiPersistentMemory] = FALSE, \
+ [EfiUnacceptedMemoryType] = TRUE, \
+ [OEM_RESERVED_MPS_MEMORY_TYPE] = TRUE, \
+ [OS_RESERVED_MPS_MEMORY_TYPE] = TRUE \
+ } \
+ }, \
+ { /* Heap Guard */ \
+ .PageGuardEnabled = TRUE, \
+ .PoolGuardEnabled = FALSE, \
+ .FreedMemoryGuardEnabled = FALSE, \
+ .NonstopModeEnabled = FALSE, \
+ .GuardAlignedToTail = FALSE \
+ }, \
+ { /* Pool Guard */ \
+ 0 \
+ }, \
+ { /* Page Guard */ \
+ .EnabledForType = { \
+ [EfiReservedMemoryType] = FALSE, \
+ [EfiLoaderCode] = FALSE, \
+ [EfiLoaderData] = FALSE, \
+ [EfiBootServicesCode] = FALSE, \
+ [EfiBootServicesData] = TRUE, \
+ [EfiRuntimeServicesCode] = FALSE, \
+ [EfiRuntimeServicesData] = TRUE, \
+ [EfiConventionalMemory] = FALSE, \
+ [EfiUnusableMemory] = FALSE, \
+ [EfiACPIReclaimMemory] = FALSE, \
+ [EfiACPIMemoryNVS] = FALSE, \
+ [EfiMemoryMappedIO] = FALSE, \
+ [EfiMemoryMappedIOPortSpace] = FALSE, \
+ [EfiPalCode] = FALSE, \
+ [EfiPersistentMemory] = FALSE, \
+ [EfiUnacceptedMemoryType] = FALSE, \
+ [OEM_RESERVED_MPS_MEMORY_TYPE] = FALSE, \
+ [OS_RESERVED_MPS_MEMORY_TYPE] = FALSE \
+ } \
+ } \
+ };
+
+//
+// A memory profile which mirrors DXE_MEMORY_PROTECTION_SETTINGS_PROD_MODE
+// but doesn't include page guards.
+//
+#define DXE_MEMORY_PROTECTION_SETTINGS_PROD_MODE_NO_PAGE_GUARDS \
+ { \
+ DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION, \
+ TRUE, /* Stack Guard */ \
+ TRUE, /* Stack Execution Protection */ \
+ { /* NULL Pointer Detection */ \
+ .Enabled = TRUE, \
+ .DisableEndOfDxe = FALSE, \
+ .NonstopModeEnabled = FALSE \
+ }, \
+ { /* Image Protection */ \
+ .ProtectImageFromUnknown = FALSE, \
+ .ProtectImageFromFv = TRUE \
+ }, \
+ { /* Execution Protection */ \
+ .EnabledForType = { \
+ [EfiReservedMemoryType] = TRUE, \
+ [EfiLoaderCode] = FALSE, \
+ [EfiLoaderData] = TRUE, \
+ [EfiBootServicesCode] = FALSE, \
+ [EfiBootServicesData] = TRUE, \
+ [EfiRuntimeServicesCode] = FALSE, \
+ [EfiRuntimeServicesData] = TRUE, \
+ [EfiConventionalMemory] = TRUE, \
+ [EfiUnusableMemory] = TRUE, \
+ [EfiACPIReclaimMemory] = TRUE, \
+ [EfiACPIMemoryNVS] = TRUE, \
+ [EfiMemoryMappedIO] = TRUE, \
+ [EfiMemoryMappedIOPortSpace] = TRUE, \
+ [EfiPalCode] = TRUE, \
+ [EfiPersistentMemory] = FALSE, \
+ [EfiUnacceptedMemoryType] = TRUE, \
+ [OEM_RESERVED_MPS_MEMORY_TYPE] = TRUE, \
+ [OS_RESERVED_MPS_MEMORY_TYPE] = TRUE \
+ } \
+ }, \
+ { /* Heap Guard */ \
+ 0 \
+ }, \
+ { /* Pool Guard */ \
+ 0 \
+ }, \
+ { /* Page Guard */ \
+ 0 \
+ } \
+ };
+
+//
+// A memory profile which disables all DXE memory protection settings.
+//
+#define DXE_MEMORY_PROTECTION_SETTINGS_OFF \
+ { \
+ DXE_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION, \
+ FALSE, /* Stack Guard */ \
+ FALSE, /* Stack Execution Protection */ \
+ { /* NULL Pointer Detection */ \
+ 0 \
+ }, \
+ { /* Image Protection */ \
+ 0 \
+ }, \
+ { /* Execution Protection */ \
+ 0 \
+ }, \
+ { /* Heap Guard */ \
+ 0 \
+ }, \
+ { /* Pool Guard */ \
+ 0 \
+ }, \
+ { /* Page Guard */ \
+ 0 \
+ } \
+ };
+
+#endif
diff --git a/MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h b/MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h
new file mode 100644
index 0000000000..383788b8f3
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/MmMemoryProtectionSettings.h
@@ -0,0 +1,211 @@
+/** @file
+
+Defines memory protection settings guid and struct for MM.
+
+Copyright (C) Microsoft Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_MEMORY_PROTECTION_SETTINGS_H_
+#define MM_MEMORY_PROTECTION_SETTINGS_H_
+
+#include <Library/BaseMemoryLib.h>
+
+// Current iteration of MM_MEMORY_PROTECTION_SETTINGS
+#define MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION 1
+
+#define OEM_RESERVED_MPS_MEMORY_TYPE EfiMaxMemoryType
+#define OS_RESERVED_MPS_MEMORY_TYPE (EfiMaxMemoryType + 1)
+#define MAX_MM_MPS_MEMORY_TYPE (EfiMaxMemoryType + 2)
+#define MM_MPS_MEMORY_TYPE_BUFFER_SIZE (MAX_MM_MPS_MEMORY_TYPE * sizeof (BOOLEAN))
+
+typedef struct {
+ BOOLEAN Enabled : 1;
+ BOOLEAN NonstopModeEnabled : 1;
+} MM_NULL_DETECTION_POLICY;
+
+typedef struct {
+ BOOLEAN PageGuardEnabled : 1;
+ BOOLEAN PoolGuardEnabled : 1;
+ BOOLEAN NonstopModeEnabled : 1;
+ BOOLEAN GuardAlignedToTail : 1;
+} MM_HEAP_GUARD_POLICY;
+
+typedef struct {
+ BOOLEAN EnabledForType[MAX_MM_MPS_MEMORY_TYPE];
+} MM_MPS_MEMORY_TYPES;
+
+typedef UINT8 MM_MEMORY_PROTECTION_SETTINGS_VERSION;
+
+//
+// Memory Protection Settings struct
+//
+typedef struct {
+ // The current version of the structure definition. This is used to ensure there isn't a
+ // definition mismatch if modules have differing iterations of this header. When creating
+ // this struct, use the MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION macro.
+ MM_MEMORY_PROTECTION_SETTINGS_VERSION StructVersion;
+
+ // If enabled, accessing the NULL address in MM will be caught by marking
+ // the NULL page as not present.
+ // .NullDetectionEnabled : Enable NULL pointer detection.
+ // .NonstopModeEnabled : If enabled the debug flag will be raised when a fault occurs
+ // to break into debugger.
+ MM_NULL_DETECTION_POLICY NullPointerDetection;
+
+ // Configures general heap guard behavior.
+ //
+ // Note:
+ // a) Due to the limit of pool memory implementation and the alignment
+ // requirement of UEFI spec, HeapGuard.GuardAlignedToTail is a try-best
+ // setting which cannot guarantee that the returned pool is exactly
+ // adjacent to head or tail guard page.
+ //
+ // .PageGuardEnabled : Enable page guard.
+ // .PoolGuardEnabled : Enable pool guard.
+ // .NonstopModeEnabled : If enabled the debug flag will be raised when a fault occurs
+ // to break into debugger.
+ // .GuardAlignedToTail : TRUE if the pool is aligned to tail guard page. If FALSE, the
+ // pool is aligned to head guard page.
+ MM_HEAP_GUARD_POLICY HeapGuard;
+
+ // Indicates which type allocation need guard page.
+ //
+ // If bit is set, a head guard page and a tail guard page will be added just
+ // before and after corresponding type of pages which the allocated pool occupies,
+ // if there's enough free memory for all of them.
+ //
+ // These settings are only valid if PoolGuardEnabled is TRUE in HeapGuard.
+ MM_MPS_MEMORY_TYPES PoolGuard;
+
+ // Indicates which type allocation need guard page.
+ //
+ // If a bit is set, a head guard page and a tail guard page will be added just
+ // before and after corresponding type of pages allocated if there's enough
+ // free pages for all of them.
+ //
+ // This bitfield is only valid if PageGuardEnabled is TRUE in HeapGuard.
+ MM_MPS_MEMORY_TYPES PageGuard;
+} MM_MEMORY_PROTECTION_SETTINGS;
+
+#define MM_MPS_IS_STRUCT_VALID(MmMpsPtr) \
+ (((MM_MEMORY_PROTECTION_SETTINGS *)MmMpsPtr)->StructVersion == MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION)
+
+#define MM_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(MpsMemoryTypesPtr) \
+ (!IsZeroBuffer (&((MM_MPS_MEMORY_TYPES *)MpsMemoryTypesPtr)->EnabledForType, MM_MPS_MEMORY_TYPE_BUFFER_SIZE))
+
+#define MM_MPS_IS_IMAGE_PROTECTION_ENABLED(MmMpsPtr) \
+ (((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->ImageProtection.ProtectImageFromFv || \
+ ((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->ImageProtection.ProtectImageFromUnknown)
+
+#define MM_MPS_IS_EXECUTION_PROTECTION_ENABLED(MmMpsPtr) \
+ MM_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->ExecutionProtection)
+
+#define MM_MPS_ARE_PAGE_GUARDS_ENABLED(MmMpsPtr) \
+ (((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->HeapGuard.PageGuardEnabled && \
+ MM_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->PageGuard))
+
+#define MM_MPS_ARE_POOL_GUARDS_ENABLED(MmMpsPtr) \
+ (((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->HeapGuard.PoolGuardEnabled && \
+ MM_MPS_IS_ANY_MEMORY_TYPE_ACTIVE(&((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->PoolGuard))
+
+#define MM_MPS_IS_MEMORY_PROTECTION_ACTIVE(MmMpsPtr) \
+ (MM_MPS_IS_STRUCT_VALID(MmMpsPtr) && \
+ (((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->CpuStackGuardEnabled || \
+ ((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->StackExecutionProtectionEnabled || \
+ ((MM_MEMORY_PROTECTION_SETTINGS*)MmMpsPtr)->NullPointerDetection.Enabled || \
+ MM_MPS_IS_IMAGE_PROTECTION_ENABLED(MmMpsPtr) || \
+ MM_MPS_IS_EXECUTION_PROTECTION_ENABLED(MmMpsPtr) || \
+ MM_MPS_ARE_PAGE_GUARDS_ENABLED(MmMpsPtr) || \
+ MM_MPS_ARE_POOL_GUARDS_ENABLED(MmMpsPtr)) \
+ )
+
+#define HOB_MM_MEMORY_PROTECTION_SETTINGS_GUID \
+ { \
+ { 0x0CF445DD, 0xA67C, 0x4F8C, { 0x81, 0x9B, 0xB7, 0xB6, 0x86, 0xED, 0x7C, 0x75 } } \
+ }
+
+extern GUID gMmMemoryProtectionSettingsGuid;
+
+//
+// A memory profile ideal for development scenarios.
+//
+#define MM_MEMORY_PROTECTION_SETTINGS_DEBUG { \
+ MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION, \
+ { /* NULL Pointer Detection */ \
+ .Enabled = TRUE, \
+ .NonstopModeEnabled = TRUE \
+ }, \
+ { /* Heap Guard */ \
+ .PageGuardEnabled = TRUE, \
+ .PoolGuardEnabled = TRUE, \
+ .NonstopModeEnabled = TRUE, \
+ .GuardAlignedToTail = FALSE \
+ }, \
+ { /* Pool Guard */ \
+ .EnabledForType = { \
+ [EfiReservedMemoryType] = FALSE, \
+ [EfiLoaderCode] = FALSE, \
+ [EfiLoaderData] = FALSE, \
+ [EfiBootServicesCode] = FALSE, \
+ [EfiBootServicesData] = TRUE, \
+ [EfiRuntimeServicesCode] = FALSE, \
+ [EfiRuntimeServicesData] = TRUE, \
+ [EfiConventionalMemory] = FALSE, \
+ [EfiUnusableMemory] = FALSE, \
+ [EfiACPIReclaimMemory] = FALSE, \
+ [EfiACPIMemoryNVS] = FALSE, \
+ [EfiMemoryMappedIO] = FALSE, \
+ [EfiMemoryMappedIOPortSpace] = FALSE, \
+ [EfiPalCode] = FALSE, \
+ [EfiPersistentMemory] = FALSE, \
+ [EfiUnacceptedMemoryType] = FALSE, \
+ [OEM_RESERVED_MPS_MEMORY_TYPE] = FALSE, \
+ [OS_RESERVED_MPS_MEMORY_TYPE] = FALSE \
+ } \
+ }, \
+ { /* Page Guard */ \
+ .EnabledForType = { \
+ [EfiReservedMemoryType] = FALSE, \
+ [EfiLoaderCode] = FALSE, \
+ [EfiLoaderData] = FALSE, \
+ [EfiBootServicesCode] = FALSE, \
+ [EfiBootServicesData] = TRUE, \
+ [EfiRuntimeServicesCode] = FALSE, \
+ [EfiRuntimeServicesData] = TRUE, \
+ [EfiConventionalMemory] = FALSE, \
+ [EfiUnusableMemory] = FALSE, \
+ [EfiACPIReclaimMemory] = FALSE, \
+ [EfiACPIMemoryNVS] = FALSE, \
+ [EfiMemoryMappedIO] = FALSE, \
+ [EfiMemoryMappedIOPortSpace] = FALSE, \
+ [EfiPalCode] = FALSE, \
+ [EfiPersistentMemory] = FALSE, \
+ [EfiUnacceptedMemoryType] = FALSE, \
+ [OEM_RESERVED_MPS_MEMORY_TYPE] = FALSE, \
+ [OS_RESERVED_MPS_MEMORY_TYPE] = FALSE \
+ } \
+ } \
+ }
+
+//
+// A memory profile which disables all MM memory protection settings.
+//
+#define MM_MEMORY_PROTECTION_SETTINGS_OFF { \
+ MM_MEMORY_PROTECTION_SETTINGS_CURRENT_VERSION, \
+ { /* NULL Pointer Detection */ \
+ 0 \
+ }, \
+ { /* Heap Guard */ \
+ 0 \
+ }, \
+ { /* Pool Guard */ \
+ 0 \
+ }, \
+ { /* Page Guard */ \
+ 0 \
+ } \
+ }
+
+#endif
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index d65dae18aa..f8c0fb4e93 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -399,6 +399,16 @@
## Include/Guid/EndofS3Resume.h
gEdkiiEndOfS3ResumeGuid = { 0x96f5296d, 0x05f7, 0x4f3c, {0x84, 0x67, 0xe4, 0x56, 0x89, 0x0e, 0x0c, 0xb5 } }
+ ## DXE Memory Protection Settings Guid. Used to create and fetch the DXE memory protection settings HOB entry.
+ #
+ # Include/Guid/DxeMemoryProtectionSettings
+ gDxeMemoryProtectionSettingsGuid = { 0x9ABFD639, 0xD1D0, 0x4EFF, { 0xBD, 0xB6, 0x7E, 0xC4, 0x19, 0x0D, 0x17, 0xD5 }}
+
+ ## SMM Memory Protection Settings Guid. Used to create and fetch the SMM memory protection settings HOB entry.
+ #
+ # Include/Guid/MmMemoryProtectionSettings
+ gMmMemoryProtectionSettingsGuid = { 0x0CF445DD, 0xA67C, 0x4F8C, { 0x81, 0x9B, 0xB7, 0xB6, 0x86, 0xED, 0x7C, 0x75 }}
+
## Used (similar to Variable Services) to communicate policies to the enforcement engine.
# {DA1B0D11-D1A7-46C4-9DC9-F3714875C6EB}
gVarCheckPolicyLibMmiHandlerGuid = { 0xda1b0d11, 0xd1a7, 0x46c4, { 0x9d, 0xc9, 0xf3, 0x71, 0x48, 0x75, 0xc6, 0xeb }}
--
2.41.0.windows.2
next prev parent reply other threads:[~2023-07-11 23:53 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-11 23:52 [PATCH 00/14] Implement Dynamic Memory Protections Taylor Beebe
2023-07-11 23:52 ` Taylor Beebe [this message]
2023-07-11 23:52 ` [PATCH 02/14] MdeModulePkg: Add MemoryProtectionHobLib Definitions and NULL Libs Taylor Beebe
2023-07-11 23:52 ` [PATCH 03/14] MdeModulePkg: Add Phase-Specific MemoryProtectionHobLib Implementations Taylor Beebe
2023-07-11 23:52 ` [PATCH 04/14] OvmfPkg: Create the memory protection settings HOB Taylor Beebe
2023-07-11 23:52 ` [PATCH 05/14] ArmVirtPkg: Create " Taylor Beebe
2023-07-11 23:52 ` [PATCH 06/14] ArmPkg: Update to use memory protection HOB Taylor Beebe
2023-07-11 23:52 ` [PATCH 07/14] EmulatorPkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 08/14] MdeModulePkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 09/14] OvmfPkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 10/14] UefiCpuPkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 11/14] UefiPayloadPkg: " Taylor Beebe
2023-07-11 23:52 ` [PATCH 12/14] OvmfPkg: Delete Memory Protection PCDs Taylor Beebe
2023-07-11 23:52 ` [PATCH 14/14] MdeModulePkg: " Taylor Beebe
2023-07-11 23:52 ` Taylor Beebe
[not found] ` <1770F551E2E594C0.16575@groups.io>
2023-07-12 0:01 ` [edk2-devel] " Taylor Beebe
2023-07-12 10:05 ` [PATCH 00/14] Implement Dynamic Memory Protections Gerd Hoffmann
2023-07-12 21:54 ` Taylor Beebe
2023-07-17 11:14 ` [edk2-devel] " Gerd Hoffmann
2023-07-17 16:15 ` Pedro Falcato
2023-07-17 16:25 ` Ard Biesheuvel
2023-07-17 16:49 ` Pedro Falcato
2023-07-18 2:45 ` Taylor Beebe
2023-07-18 6:11 ` Ni, Ray
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=90e3068695d8dc23c940e7f8ad00a7efc6d91bd6.1689101263.git.t@taylorbeebe.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox