summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Smith-Denny <osde@microsoft.com>2025-06-17 15:29:13 -0700
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2025-07-08 03:45:09 +0000
commit91bb5cee36fe52ef012ddbead4f5932b3f9fd862 (patch)
treecdeeb4a1599e5a0905fdee1ec44d3c356a8d21ac
parent83b30736bfb57b3895a089968319fb5c0cd42a28 (diff)
downloadedk2-91bb5cee36fe52ef012ddbead4f5932b3f9fd862.zip
edk2-91bb5cee36fe52ef012ddbead4f5932b3f9fd862.tar.gz
edk2-91bb5cee36fe52ef012ddbead4f5932b3f9fd862.tar.bz2
MdeModulePkg: Don't Allocate Page 0
Currently DxeIpl attempts to set page 0 to all 0's and to create a memory allocation HOB for it. However, DxeIpl will also unmap the page when mapping page tables and if null detection is not enabled, DxeCore will set the page to 0, regardless of allocation status. Because no consumers are using the memory allocation HOB for page 0, drop it. Instead, ensure that PeiCore and DxeCore do not allow allocating page 0; it should always be reserved for null pointer detection. It also complicates the story for platforms that are attempting to audit the system and ensure that no modules are using page 0. With these memory allocation HOBs in place, it is difficult to tell if it is simply DxeIpl who has allocated the memory or another module. This commit drops the memory allocation HOB publishing and ensures that DxeCore and PeiCore do not allocate page 0. DxeCore already will not allocate page 0 to callers of AllocatePages who call with a type other than AllocateAddress, this just changes so that AllocateAddress cannot allocate at page 0 (which if null detection is enabled will cause a page fault). PeiCore does not have AllocateAddress and so this ensures standard allocations do not receive page 0. Signed-off-by: Oliver Smith-Denny <osde@microsoft.com>
-rw-r--r--MdeModulePkg/Core/Dxe/Mem/Page.c5
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c8
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c8
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c66
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h14
-rw-r--r--MdeModulePkg/Core/Pei/Memory/MemoryServices.c5
6 files changed, 8 insertions, 98 deletions
diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c
index e4daa74..9df64cc 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Page.c
+++ b/MdeModulePkg/Core/Dxe/Mem/Page.c
@@ -1459,6 +1459,11 @@ CoreInternalAllocatePages (
// return EFI_NOT_FOUND.
//
if (Type == AllocateAddress) {
+ // Page 0 is not allowed to be allocated as it is reserved for null pointer detection
+ if (Start == 0) {
+ return EFI_NOT_FOUND;
+ }
+
if ((NumberOfPages == 0) ||
(NumberOfPages > RShiftU64 (MaxAddress, EFI_PAGE_SHIFT)))
{
diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
index 60878b4..98aae5a 100644
--- a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
@@ -265,14 +265,6 @@ HandOffToDxeCore (
EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;
BOOLEAN BuildPageTablesIa32Pae;
- //
- // Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
- //
- if (IsNullDetectionEnabled ()) {
- ClearFirst4KPage (HobList.Raw);
- BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1), EfiBootServicesData);
- }
-
Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);
ASSERT_EFI_ERROR (Status);
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
index fa2050c..034254b 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c
@@ -37,14 +37,6 @@ HandOffToDxeCore (
UINTN GhcbSize;
//
- // Clear page 0 and mark it as allocated if NULL pointer detection is enabled.
- //
- if (IsNullDetectionEnabled ()) {
- ClearFirst4KPage (HobList.Raw);
- BuildMemoryAllocationHob (0, EFI_PAGES_TO_SIZE (1), EfiBootServicesData);
- }
-
- //
// Get Vector Hand-off Info PPI and build Guided HOB
//
Status = PeiServicesLocatePpi (
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
index 1fb2a3b..ee85b31 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c
@@ -32,72 +32,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
PAGE_TABLE_POOL *mPageTablePool = NULL;
/**
- Clear legacy memory located at the first 4K-page, if available.
-
- This function traverses the whole HOB list to check if memory from 0 to 4095
- exists and has not been allocated, and then clear it if so.
-
- @param HobStart The start of HobList passed to DxeCore.
-
-**/
-VOID
-ClearFirst4KPage (
- IN VOID *HobStart
- )
-{
- EFI_PEI_HOB_POINTERS RscHob;
- EFI_PEI_HOB_POINTERS MemHob;
- BOOLEAN DoClear;
-
- RscHob.Raw = HobStart;
- MemHob.Raw = HobStart;
- DoClear = FALSE;
-
- //
- // Check if page 0 exists and free
- //
- while ((RscHob.Raw = GetNextHob (
- EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
- RscHob.Raw
- )) != NULL)
- {
- if ((RscHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
- (RscHob.ResourceDescriptor->PhysicalStart == 0))
- {
- DoClear = TRUE;
- //
- // Make sure memory at 0-4095 has not been allocated.
- //
- while ((MemHob.Raw = GetNextHob (
- EFI_HOB_TYPE_MEMORY_ALLOCATION,
- MemHob.Raw
- )) != NULL)
- {
- if (MemHob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress
- < EFI_PAGE_SIZE)
- {
- DoClear = FALSE;
- break;
- }
-
- MemHob.Raw = GET_NEXT_HOB (MemHob);
- }
-
- break;
- }
-
- RscHob.Raw = GET_NEXT_HOB (RscHob);
- }
-
- if (DoClear) {
- DEBUG ((DEBUG_INFO, "Clearing first 4K-page!\r\n"));
- SetMem (NULL, EFI_PAGE_SIZE, 0);
- }
-
- return;
-}
-
-/**
Return configure status of NULL pointer detection feature.
@return TRUE NULL pointer detection feature is enabled
diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h
index e035284..95e88a9 100644
--- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h
+++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h
@@ -268,20 +268,6 @@ AsmGetVectorTemplatInfo (
);
/**
- Clear legacy memory located at the first 4K-page.
-
- This function traverses the whole HOB list to check if memory from 0 to 4095
- exists and has not been allocated, and then clear it if so.
-
- @param HobStart The start of HobList passed to DxeCore.
-
-**/
-VOID
-ClearFirst4KPage (
- IN VOID *HobStart
- );
-
-/**
Return configure status of NULL pointer detection feature.
@return TRUE NULL pointer detection feature is enabled
diff --git a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
index 562092d..80b2f89 100644
--- a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
+++ b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c
@@ -613,10 +613,11 @@ PeiAllocatePages (
//
// Check to see if on correct boundary for the memory type.
- // If not aligned, make the allocation aligned.
+ // If not aligned, make the allocation aligned and that we are not trying to allocate page 0, which is used for
+ // null detection.
//
Padding = *(FreeMemoryTop) & (Granularity - 1);
- if ((UINTN)(*FreeMemoryTop - *FreeMemoryBottom) < Padding) {
+ if (((UINTN)(*FreeMemoryTop - *FreeMemoryBottom) < Padding) || (*(FreeMemoryTop) - Padding == 0)) {
DEBUG ((DEBUG_ERROR, "AllocatePages failed: Out of space after padding.\n"));
return EFI_OUT_OF_RESOURCES;
}