From: "Taylor Beebe" <t@taylorbeebe.com>
To: devel@edk2.groups.io
Cc: Taylor Beebe <t@taylorbeebe.com>,
Jian J Wang <jian.j.wang@intel.com>,
Liming Gao <gaoliming@byosoft.com.cn>,
Dandan Bi <dandan.bi@intel.com>
Subject: [PATCH v1 1/3] MdeModulePkg: Add DXE and MM Memory Protection Settings HOB Definitions
Date: Fri, 9 Jun 2023 13:25:59 -0700 [thread overview]
Message-ID: <20230609202601.1153-2-t@taylorbeebe.com> (raw)
In-Reply-To: <20230609202601.1153-1-t@taylorbeebe.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>
---
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
next prev parent reply other threads:[~2023-06-09 20:26 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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
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=20230609202601.1153-2-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