UEFI Heap Guard functions.\r
\r
Copyright (c) 2017-2018, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
// Global to avoid infinite reentrance of memory allocation when updating\r
// page table attributes, which may need allocate pages for new PDE/PTE.\r
//\r
-GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mOnGuarding = FALSE;\r
+GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mOnGuarding = FALSE;\r
\r
//\r
// Pointer to table tracking the Guarded memory with bitmap, in which '1'\r
// is used to indicate memory guarded. '0' might be free memory or Guard\r
// page itself, depending on status of memory adjacent to it.\r
//\r
-GLOBAL_REMOVE_IF_UNREFERENCED UINT64 mGuardedMemoryMap = 0;\r
+GLOBAL_REMOVE_IF_UNREFERENCED UINT64 mGuardedMemoryMap = 0;\r
\r
//\r
// Current depth level of map table pointed by mGuardedMemoryMap.\r
// mMapLevel must be initialized at least by 1. It will be automatically\r
// updated according to the address of memory just tracked.\r
//\r
-GLOBAL_REMOVE_IF_UNREFERENCED UINTN mMapLevel = 1;\r
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN mMapLevel = 1;\r
\r
//\r
// Shift and mask for each level of map table\r
//\r
-GLOBAL_REMOVE_IF_UNREFERENCED UINTN mLevelShift[GUARDED_HEAP_MAP_TABLE_DEPTH]\r
- = GUARDED_HEAP_MAP_TABLE_DEPTH_SHIFTS;\r
-GLOBAL_REMOVE_IF_UNREFERENCED UINTN mLevelMask[GUARDED_HEAP_MAP_TABLE_DEPTH]\r
- = GUARDED_HEAP_MAP_TABLE_DEPTH_MASKS;\r
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN mLevelShift[GUARDED_HEAP_MAP_TABLE_DEPTH]\r
+ = GUARDED_HEAP_MAP_TABLE_DEPTH_SHIFTS;\r
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN mLevelMask[GUARDED_HEAP_MAP_TABLE_DEPTH]\r
+ = GUARDED_HEAP_MAP_TABLE_DEPTH_MASKS;\r
+\r
+//\r
+// Used for promoting freed but not used pages.\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS mLastPromotedPage = BASE_4GB;\r
\r
/**\r
Set corresponding bits in bitmap table to 1 according to the address.\r
STATIC\r
VOID\r
SetBits (\r
- IN EFI_PHYSICAL_ADDRESS Address,\r
- IN UINTN BitNumber,\r
- IN UINT64 *BitMap\r
+ IN EFI_PHYSICAL_ADDRESS Address,\r
+ IN UINTN BitNumber,\r
+ IN UINT64 *BitMap\r
)\r
{\r
- UINTN Lsbs;\r
- UINTN Qwords;\r
- UINTN Msbs;\r
- UINTN StartBit;\r
- UINTN EndBit;\r
+ UINTN Lsbs;\r
+ UINTN Qwords;\r
+ UINTN Msbs;\r
+ UINTN StartBit;\r
+ UINTN EndBit;\r
\r
- StartBit = (UINTN)GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address);\r
- EndBit = (StartBit + BitNumber - 1) % GUARDED_HEAP_MAP_ENTRY_BITS;\r
+ StartBit = (UINTN)GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address);\r
+ EndBit = (StartBit + BitNumber - 1) % GUARDED_HEAP_MAP_ENTRY_BITS;\r
\r
if ((StartBit + BitNumber) >= GUARDED_HEAP_MAP_ENTRY_BITS) {\r
- Msbs = (GUARDED_HEAP_MAP_ENTRY_BITS - StartBit) %\r
- GUARDED_HEAP_MAP_ENTRY_BITS;\r
- Lsbs = (EndBit + 1) % GUARDED_HEAP_MAP_ENTRY_BITS;\r
- Qwords = (BitNumber - Msbs) / GUARDED_HEAP_MAP_ENTRY_BITS;\r
+ Msbs = (GUARDED_HEAP_MAP_ENTRY_BITS - StartBit) %\r
+ GUARDED_HEAP_MAP_ENTRY_BITS;\r
+ Lsbs = (EndBit + 1) % GUARDED_HEAP_MAP_ENTRY_BITS;\r
+ Qwords = (BitNumber - Msbs) / GUARDED_HEAP_MAP_ENTRY_BITS;\r
} else {\r
- Msbs = BitNumber;\r
- Lsbs = 0;\r
- Qwords = 0;\r
+ Msbs = BitNumber;\r
+ Lsbs = 0;\r
+ Qwords = 0;\r
}\r
\r
if (Msbs > 0) {\r
}\r
\r
if (Qwords > 0) {\r
- SetMem64 ((VOID *)BitMap, Qwords * GUARDED_HEAP_MAP_ENTRY_BYTES,\r
- (UINT64)-1);\r
+ SetMem64 (\r
+ (VOID *)BitMap,\r
+ Qwords * GUARDED_HEAP_MAP_ENTRY_BYTES,\r
+ (UINT64)-1\r
+ );\r
BitMap += Qwords;\r
}\r
\r
STATIC\r
VOID\r
ClearBits (\r
- IN EFI_PHYSICAL_ADDRESS Address,\r
- IN UINTN BitNumber,\r
- IN UINT64 *BitMap\r
+ IN EFI_PHYSICAL_ADDRESS Address,\r
+ IN UINTN BitNumber,\r
+ IN UINT64 *BitMap\r
)\r
{\r
- UINTN Lsbs;\r
- UINTN Qwords;\r
- UINTN Msbs;\r
- UINTN StartBit;\r
- UINTN EndBit;\r
+ UINTN Lsbs;\r
+ UINTN Qwords;\r
+ UINTN Msbs;\r
+ UINTN StartBit;\r
+ UINTN EndBit;\r
\r
- StartBit = (UINTN)GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address);\r
- EndBit = (StartBit + BitNumber - 1) % GUARDED_HEAP_MAP_ENTRY_BITS;\r
+ StartBit = (UINTN)GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address);\r
+ EndBit = (StartBit + BitNumber - 1) % GUARDED_HEAP_MAP_ENTRY_BITS;\r
\r
if ((StartBit + BitNumber) >= GUARDED_HEAP_MAP_ENTRY_BITS) {\r
- Msbs = (GUARDED_HEAP_MAP_ENTRY_BITS - StartBit) %\r
- GUARDED_HEAP_MAP_ENTRY_BITS;\r
- Lsbs = (EndBit + 1) % GUARDED_HEAP_MAP_ENTRY_BITS;\r
- Qwords = (BitNumber - Msbs) / GUARDED_HEAP_MAP_ENTRY_BITS;\r
+ Msbs = (GUARDED_HEAP_MAP_ENTRY_BITS - StartBit) %\r
+ GUARDED_HEAP_MAP_ENTRY_BITS;\r
+ Lsbs = (EndBit + 1) % GUARDED_HEAP_MAP_ENTRY_BITS;\r
+ Qwords = (BitNumber - Msbs) / GUARDED_HEAP_MAP_ENTRY_BITS;\r
} else {\r
- Msbs = BitNumber;\r
- Lsbs = 0;\r
- Qwords = 0;\r
+ Msbs = BitNumber;\r
+ Lsbs = 0;\r
+ Qwords = 0;\r
}\r
\r
if (Msbs > 0) {\r
STATIC\r
UINT64\r
GetBits (\r
- IN EFI_PHYSICAL_ADDRESS Address,\r
- IN UINTN BitNumber,\r
- IN UINT64 *BitMap\r
+ IN EFI_PHYSICAL_ADDRESS Address,\r
+ IN UINTN BitNumber,\r
+ IN UINT64 *BitMap\r
)\r
{\r
- UINTN StartBit;\r
- UINTN EndBit;\r
- UINTN Lsbs;\r
- UINTN Msbs;\r
- UINT64 Result;\r
+ UINTN StartBit;\r
+ UINTN EndBit;\r
+ UINTN Lsbs;\r
+ UINTN Msbs;\r
+ UINT64 Result;\r
\r
ASSERT (BitNumber <= GUARDED_HEAP_MAP_ENTRY_BITS);\r
\r
- StartBit = (UINTN)GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address);\r
- EndBit = (StartBit + BitNumber - 1) % GUARDED_HEAP_MAP_ENTRY_BITS;\r
+ StartBit = (UINTN)GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address);\r
+ EndBit = (StartBit + BitNumber - 1) % GUARDED_HEAP_MAP_ENTRY_BITS;\r
\r
if ((StartBit + BitNumber) > GUARDED_HEAP_MAP_ENTRY_BITS) {\r
Msbs = GUARDED_HEAP_MAP_ENTRY_BITS - StartBit;\r
Lsbs = 0;\r
}\r
\r
- if (StartBit == 0 && BitNumber == GUARDED_HEAP_MAP_ENTRY_BITS) {\r
+ if ((StartBit == 0) && (BitNumber == GUARDED_HEAP_MAP_ENTRY_BITS)) {\r
Result = *BitMap;\r
} else {\r
- Result = RShiftU64((*BitMap), StartBit) & (LShiftU64(1, Msbs) - 1);\r
+ Result = RShiftU64 ((*BitMap), StartBit) & (LShiftU64 (1, Msbs) - 1);\r
if (Lsbs > 0) {\r
- BitMap += 1;\r
- Result |= LShiftU64 ((*BitMap) & (LShiftU64 (1, Lsbs) - 1), Msbs);\r
+ BitMap += 1;\r
+ Result |= LShiftU64 ((*BitMap) & (LShiftU64 (1, Lsbs) - 1), Msbs);\r
}\r
}\r
\r
**/\r
UINTN\r
FindGuardedMemoryMap (\r
- IN EFI_PHYSICAL_ADDRESS Address,\r
- IN BOOLEAN AllocMapUnit,\r
- OUT UINT64 **BitMap\r
+ IN EFI_PHYSICAL_ADDRESS Address,\r
+ IN BOOLEAN AllocMapUnit,\r
+ OUT UINT64 **BitMap\r
)\r
{\r
- UINTN Level;\r
- UINT64 *GuardMap;\r
- UINT64 MapMemory;\r
- UINTN Index;\r
- UINTN Size;\r
- UINTN BitsToUnitEnd;\r
- EFI_STATUS Status;\r
+ UINTN Level;\r
+ UINT64 *GuardMap;\r
+ UINT64 MapMemory;\r
+ UINTN Index;\r
+ UINTN Size;\r
+ UINTN BitsToUnitEnd;\r
+ EFI_STATUS Status;\r
+\r
+ MapMemory = 0;\r
\r
//\r
// Adjust current map table depth according to the address to access\r
RShiftU64 (\r
Address,\r
mLevelShift[GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel - 1]\r
- ) != 0) {\r
-\r
+ ) != 0)\r
+ {\r
if (mGuardedMemoryMap != 0) {\r
Size = (mLevelMask[GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel - 1] + 1)\r
* GUARDED_HEAP_MAP_ENTRY_BYTES;\r
Status = CoreInternalAllocatePages (\r
- AllocateAnyPages,\r
- EfiBootServicesData,\r
- EFI_SIZE_TO_PAGES (Size),\r
- &MapMemory,\r
- FALSE\r
- );\r
+ AllocateAnyPages,\r
+ EfiBootServicesData,\r
+ EFI_SIZE_TO_PAGES (Size),\r
+ &MapMemory,\r
+ FALSE\r
+ );\r
ASSERT_EFI_ERROR (Status);\r
ASSERT (MapMemory != 0);\r
\r
SetMem ((VOID *)(UINTN)MapMemory, Size, 0);\r
\r
*(UINT64 *)(UINTN)MapMemory = mGuardedMemoryMap;\r
- mGuardedMemoryMap = MapMemory;\r
+ mGuardedMemoryMap = MapMemory;\r
}\r
\r
mMapLevel++;\r
-\r
}\r
\r
GuardMap = &mGuardedMemoryMap;\r
for (Level = GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel;\r
Level < GUARDED_HEAP_MAP_TABLE_DEPTH;\r
- ++Level) {\r
-\r
+ ++Level)\r
+ {\r
if (*GuardMap == 0) {\r
if (!AllocMapUnit) {\r
GuardMap = NULL;\r
break;\r
}\r
\r
- Size = (mLevelMask[Level] + 1) * GUARDED_HEAP_MAP_ENTRY_BYTES;\r
+ Size = (mLevelMask[Level] + 1) * GUARDED_HEAP_MAP_ENTRY_BYTES;\r
Status = CoreInternalAllocatePages (\r
- AllocateAnyPages,\r
- EfiBootServicesData,\r
- EFI_SIZE_TO_PAGES (Size),\r
- &MapMemory,\r
- FALSE\r
- );\r
+ AllocateAnyPages,\r
+ EfiBootServicesData,\r
+ EFI_SIZE_TO_PAGES (Size),\r
+ &MapMemory,\r
+ FALSE\r
+ );\r
ASSERT_EFI_ERROR (Status);\r
ASSERT (MapMemory != 0);\r
\r
*GuardMap = MapMemory;\r
}\r
\r
- Index = (UINTN)RShiftU64 (Address, mLevelShift[Level]);\r
- Index &= mLevelMask[Level];\r
- GuardMap = (UINT64 *)(UINTN)((*GuardMap) + Index * sizeof (UINT64));\r
-\r
+ Index = (UINTN)RShiftU64 (Address, mLevelShift[Level]);\r
+ Index &= mLevelMask[Level];\r
+ GuardMap = (UINT64 *)(UINTN)((*GuardMap) + Index * sizeof (UINT64));\r
}\r
\r
BitsToUnitEnd = GUARDED_HEAP_MAP_BITS - GUARDED_HEAP_MAP_BIT_INDEX (Address);\r
VOID\r
EFIAPI\r
SetGuardedMemoryBits (\r
- IN EFI_PHYSICAL_ADDRESS Address,\r
- IN UINTN NumberOfPages\r
+ IN EFI_PHYSICAL_ADDRESS Address,\r
+ IN UINTN NumberOfPages\r
)\r
{\r
- UINT64 *BitMap;\r
- UINTN Bits;\r
- UINTN BitsToUnitEnd;\r
+ UINT64 *BitMap;\r
+ UINTN Bits;\r
+ UINTN BitsToUnitEnd;\r
\r
while (NumberOfPages > 0) {\r
BitsToUnitEnd = FindGuardedMemoryMap (Address, TRUE, &BitMap);\r
// Cross map unit\r
Bits = BitsToUnitEnd;\r
} else {\r
- Bits = NumberOfPages;\r
+ Bits = NumberOfPages;\r
}\r
\r
SetBits (Address, Bits, BitMap);\r
VOID\r
EFIAPI\r
ClearGuardedMemoryBits (\r
- IN EFI_PHYSICAL_ADDRESS Address,\r
- IN UINTN NumberOfPages\r
+ IN EFI_PHYSICAL_ADDRESS Address,\r
+ IN UINTN NumberOfPages\r
)\r
{\r
- UINT64 *BitMap;\r
- UINTN Bits;\r
- UINTN BitsToUnitEnd;\r
+ UINT64 *BitMap;\r
+ UINTN Bits;\r
+ UINTN BitsToUnitEnd;\r
\r
while (NumberOfPages > 0) {\r
BitsToUnitEnd = FindGuardedMemoryMap (Address, TRUE, &BitMap);\r
// Cross map unit\r
Bits = BitsToUnitEnd;\r
} else {\r
- Bits = NumberOfPages;\r
+ Bits = NumberOfPages;\r
}\r
\r
ClearBits (Address, Bits, BitMap);\r
\r
@return An integer containing the guarded memory bitmap.\r
**/\r
-UINTN\r
+UINT64\r
GetGuardedMemoryBits (\r
- IN EFI_PHYSICAL_ADDRESS Address,\r
- IN UINTN NumberOfPages\r
+ IN EFI_PHYSICAL_ADDRESS Address,\r
+ IN UINTN NumberOfPages\r
)\r
{\r
- UINT64 *BitMap;\r
- UINTN Bits;\r
- UINTN Result;\r
- UINTN Shift;\r
- UINTN BitsToUnitEnd;\r
+ UINT64 *BitMap;\r
+ UINTN Bits;\r
+ UINT64 Result;\r
+ UINTN Shift;\r
+ UINTN BitsToUnitEnd;\r
\r
ASSERT (NumberOfPages <= GUARDED_HEAP_MAP_ENTRY_BITS);\r
\r
\r
if (NumberOfPages > BitsToUnitEnd) {\r
// Cross map unit\r
- Bits = BitsToUnitEnd;\r
+ Bits = BitsToUnitEnd;\r
} else {\r
- Bits = NumberOfPages;\r
+ Bits = NumberOfPages;\r
}\r
\r
if (BitMap != NULL) {\r
UINTN\r
EFIAPI\r
GetGuardMapBit (\r
- IN EFI_PHYSICAL_ADDRESS Address\r
+ IN EFI_PHYSICAL_ADDRESS Address\r
)\r
{\r
- UINT64 *GuardMap;\r
+ UINT64 *GuardMap;\r
\r
FindGuardedMemoryMap (Address, FALSE, &GuardMap);\r
if (GuardMap != NULL) {\r
- if (RShiftU64 (*GuardMap,\r
- GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address)) & 1) {\r
+ if (RShiftU64 (\r
+ *GuardMap,\r
+ GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address)\r
+ ) & 1)\r
+ {\r
return 1;\r
}\r
}\r
return 0;\r
}\r
\r
-\r
/**\r
Check to see if the page at the given address is a Guard page or not.\r
\r
BOOLEAN\r
EFIAPI\r
IsGuardPage (\r
- IN EFI_PHYSICAL_ADDRESS Address\r
+ IN EFI_PHYSICAL_ADDRESS Address\r
)\r
{\r
- UINTN BitMap;\r
+ UINT64 BitMap;\r
\r
//\r
// There must be at least one guarded page before and/or after given\r
return ((BitMap == BIT0) || (BitMap == BIT2) || (BitMap == (BIT2 | BIT0)));\r
}\r
\r
-\r
/**\r
Check to see if the page at the given address is guarded or not.\r
\r
BOOLEAN\r
EFIAPI\r
IsMemoryGuarded (\r
- IN EFI_PHYSICAL_ADDRESS Address\r
+ IN EFI_PHYSICAL_ADDRESS Address\r
)\r
{\r
return (GetGuardMapBit (Address) == 1);\r
VOID\r
EFIAPI\r
SetGuardPage (\r
- IN EFI_PHYSICAL_ADDRESS BaseAddress\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
\r
if (gCpu == NULL) {\r
return;\r
VOID\r
EFIAPI\r
UnsetGuardPage (\r
- IN EFI_PHYSICAL_ADDRESS BaseAddress\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress\r
)\r
{\r
- UINT64 Attributes;\r
- EFI_STATUS Status;\r
+ UINT64 Attributes;\r
+ EFI_STATUS Status;\r
\r
if (gCpu == NULL) {\r
return;\r
**/\r
BOOLEAN\r
IsMemoryTypeToGuard (\r
- IN EFI_MEMORY_TYPE MemoryType,\r
- IN EFI_ALLOCATE_TYPE AllocateType,\r
- IN UINT8 PageOrPool\r
+ IN EFI_MEMORY_TYPE MemoryType,\r
+ IN EFI_ALLOCATE_TYPE AllocateType,\r
+ IN UINT8 PageOrPool\r
)\r
{\r
- UINT64 TestBit;\r
- UINT64 ConfigBit;\r
+ UINT64 TestBit;\r
+ UINT64 ConfigBit;\r
\r
if (AllocateType == AllocateAddress) {\r
return FALSE;\r
\r
if ((UINT32)MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) {\r
TestBit = BIT63;\r
- } else if ((UINT32) MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) {\r
+ } else if ((UINT32)MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) {\r
TestBit = BIT62;\r
} else if (MemoryType < EfiMaxMemoryType) {\r
TestBit = LShiftU64 (1, MemoryType);\r
**/\r
BOOLEAN\r
IsPoolTypeToGuard (\r
- IN EFI_MEMORY_TYPE MemoryType\r
+ IN EFI_MEMORY_TYPE MemoryType\r
)\r
{\r
- return IsMemoryTypeToGuard (MemoryType, AllocateAnyPages,\r
- GUARD_HEAP_TYPE_POOL);\r
+ return IsMemoryTypeToGuard (\r
+ MemoryType,\r
+ AllocateAnyPages,\r
+ GUARD_HEAP_TYPE_POOL\r
+ );\r
}\r
\r
/**\r
**/\r
BOOLEAN\r
IsPageTypeToGuard (\r
- IN EFI_MEMORY_TYPE MemoryType,\r
- IN EFI_ALLOCATE_TYPE AllocateType\r
+ IN EFI_MEMORY_TYPE MemoryType,\r
+ IN EFI_ALLOCATE_TYPE AllocateType\r
)\r
{\r
return IsMemoryTypeToGuard (MemoryType, AllocateType, GUARD_HEAP_TYPE_PAGE);\r
/**\r
Check to see if the heap guard is enabled for page and/or pool allocation.\r
\r
+ @param[in] GuardType Specify the sub-type(s) of Heap Guard.\r
+\r
@return TRUE/FALSE.\r
**/\r
BOOLEAN\r
IsHeapGuardEnabled (\r
- VOID\r
+ UINT8 GuardType\r
)\r
{\r
- return IsMemoryTypeToGuard (EfiMaxMemoryType, AllocateAnyPages,\r
- GUARD_HEAP_TYPE_POOL|GUARD_HEAP_TYPE_PAGE);\r
+ return IsMemoryTypeToGuard (EfiMaxMemoryType, AllocateAnyPages, GuardType);\r
}\r
\r
/**\r
**/\r
VOID\r
SetGuardForMemory (\r
- IN EFI_PHYSICAL_ADDRESS Memory,\r
- IN UINTN NumberOfPages\r
+ IN EFI_PHYSICAL_ADDRESS Memory,\r
+ IN UINTN NumberOfPages\r
)\r
{\r
- EFI_PHYSICAL_ADDRESS GuardPage;\r
+ EFI_PHYSICAL_ADDRESS GuardPage;\r
\r
//\r
// Set tail Guard\r
**/\r
VOID\r
UnsetGuardForMemory (\r
- IN EFI_PHYSICAL_ADDRESS Memory,\r
- IN UINTN NumberOfPages\r
+ IN EFI_PHYSICAL_ADDRESS Memory,\r
+ IN UINTN NumberOfPages\r
)\r
{\r
EFI_PHYSICAL_ADDRESS GuardPage;\r
// -------------------\r
// Start -> -1 -2\r
//\r
- GuardPage = Memory - EFI_PAGES_TO_SIZE (1);\r
+ GuardPage = Memory - EFI_PAGES_TO_SIZE (1);\r
GuardBitmap = GetGuardedMemoryBits (Memory - EFI_PAGES_TO_SIZE (2), 2);\r
if ((GuardBitmap & BIT1) == 0) {\r
//\r
// --------------------\r
// +1 +0 <- End\r
//\r
- GuardPage = Memory + EFI_PAGES_TO_SIZE (NumberOfPages);\r
+ GuardPage = Memory + EFI_PAGES_TO_SIZE (NumberOfPages);\r
GuardBitmap = GetGuardedMemoryBits (GuardPage, 2);\r
if ((GuardBitmap & BIT0) == 0) {\r
//\r
//\r
// No matter what, we just clear the mark of the Guarded memory.\r
//\r
- ClearGuardedMemoryBits(Memory, NumberOfPages);\r
+ ClearGuardedMemoryBits (Memory, NumberOfPages);\r
}\r
\r
/**\r
**/\r
UINT64\r
AdjustMemoryS (\r
- IN UINT64 Start,\r
- IN UINT64 Size,\r
- IN UINT64 SizeRequested\r
+ IN UINT64 Start,\r
+ IN UINT64 Size,\r
+ IN UINT64 SizeRequested\r
)\r
{\r
UINT64 Target;\r
// make sure alignment of the returned pool address.\r
//\r
if ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0) {\r
- SizeRequested = ALIGN_VALUE(SizeRequested, 8);\r
+ SizeRequested = ALIGN_VALUE (SizeRequested, 8);\r
}\r
\r
Target = Start + Size - SizeRequested;\r
**/\r
VOID\r
AdjustMemoryF (\r
- IN OUT EFI_PHYSICAL_ADDRESS *Memory,\r
- IN OUT UINTN *NumberOfPages\r
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory,\r
+ IN OUT UINTN *NumberOfPages\r
)\r
{\r
EFI_PHYSICAL_ADDRESS Start;\r
UINTN PagesToFree;\r
UINT64 GuardBitmap;\r
\r
- if (Memory == NULL || NumberOfPages == NULL || *NumberOfPages == 0) {\r
+ if ((Memory == NULL) || (NumberOfPages == NULL) || (*NumberOfPages == 0)) {\r
return;\r
}\r
\r
- Start = *Memory;\r
+ Start = *Memory;\r
PagesToFree = *NumberOfPages;\r
\r
//\r
// Start -> -1 -2\r
//\r
MemoryToTest = Start - EFI_PAGES_TO_SIZE (2);\r
- GuardBitmap = GetGuardedMemoryBits (MemoryToTest, 2);\r
+ GuardBitmap = GetGuardedMemoryBits (MemoryToTest, 2);\r
if ((GuardBitmap & BIT1) == 0) {\r
//\r
// Head Guard exists.\r
// +1 +0 <- End\r
//\r
MemoryToTest = Start + EFI_PAGES_TO_SIZE (PagesToFree);\r
- GuardBitmap = GetGuardedMemoryBits (MemoryToTest, 2);\r
+ GuardBitmap = GetGuardedMemoryBits (MemoryToTest, 2);\r
if ((GuardBitmap & BIT0) == 0) {\r
//\r
// Tail Guard exists.\r
PagesToFree -= 1;\r
}\r
\r
- *Memory = Start;\r
- *NumberOfPages = PagesToFree;\r
+ *Memory = Start;\r
+ *NumberOfPages = PagesToFree;\r
}\r
\r
/**\r
**/\r
VOID\r
AdjustMemoryA (\r
- IN OUT EFI_PHYSICAL_ADDRESS *Memory,\r
- IN OUT UINTN *NumberOfPages\r
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory,\r
+ IN OUT UINTN *NumberOfPages\r
)\r
{\r
//\r
**/\r
VOID *\r
AdjustPoolHeadA (\r
- IN EFI_PHYSICAL_ADDRESS Memory,\r
- IN UINTN NoPages,\r
- IN UINTN Size\r
+ IN EFI_PHYSICAL_ADDRESS Memory,\r
+ IN UINTN NoPages,\r
+ IN UINTN Size\r
)\r
{\r
- if (Memory == 0 || (PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0) {\r
+ if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) {\r
//\r
// Pool head is put near the head Guard\r
//\r
**/\r
VOID *\r
AdjustPoolHeadF (\r
- IN EFI_PHYSICAL_ADDRESS Memory\r
+ IN EFI_PHYSICAL_ADDRESS Memory\r
)\r
{\r
- if (Memory == 0 || (PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0) {\r
+ if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) {\r
//\r
// Pool head is put near the head Guard\r
//\r
VOID\r
)\r
{\r
- UINTN Entries[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
- UINTN Shifts[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
- UINTN Indices[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
- UINT64 Tables[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
- UINT64 Addresses[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
- UINT64 TableEntry;\r
- UINT64 Address;\r
- UINT64 GuardPage;\r
- INTN Level;\r
- UINTN Index;\r
- BOOLEAN OnGuarding;\r
-\r
- if (mGuardedMemoryMap == 0 ||\r
- mMapLevel == 0 ||\r
- mMapLevel > GUARDED_HEAP_MAP_TABLE_DEPTH) {\r
+ UINTN Entries[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINTN Shifts[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINTN Indices[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINT64 Tables[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINT64 Addresses[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINT64 TableEntry;\r
+ UINT64 Address;\r
+ UINT64 GuardPage;\r
+ INTN Level;\r
+ UINTN Index;\r
+ BOOLEAN OnGuarding;\r
+\r
+ if ((mGuardedMemoryMap == 0) ||\r
+ (mMapLevel == 0) ||\r
+ (mMapLevel > GUARDED_HEAP_MAP_TABLE_DEPTH))\r
+ {\r
return;\r
}\r
\r
CopyMem (Entries, mLevelMask, sizeof (Entries));\r
CopyMem (Shifts, mLevelShift, sizeof (Shifts));\r
\r
- SetMem (Tables, sizeof(Tables), 0);\r
- SetMem (Addresses, sizeof(Addresses), 0);\r
- SetMem (Indices, sizeof(Indices), 0);\r
+ SetMem (Tables, sizeof (Tables), 0);\r
+ SetMem (Addresses, sizeof (Addresses), 0);\r
+ SetMem (Indices, sizeof (Indices), 0);\r
\r
Level = GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel;\r
Tables[Level] = mGuardedMemoryMap;\r
\r
DEBUG_CODE (\r
DumpGuardedMemoryBitmap ();\r
- );\r
+ );\r
\r
while (TRUE) {\r
if (Indices[Level] > Entries[Level]) {\r
Tables[Level] = 0;\r
Level -= 1;\r
} else {\r
-\r
- TableEntry = ((UINT64 *)(UINTN)(Tables[Level]))[Indices[Level]];\r
- Address = Addresses[Level];\r
+ TableEntry = ((UINT64 *)(UINTN)(Tables[Level]))[Indices[Level]];\r
+ Address = Addresses[Level];\r
\r
if (TableEntry == 0) {\r
-\r
OnGuarding = FALSE;\r
-\r
} else if (Level < GUARDED_HEAP_MAP_TABLE_DEPTH - 1) {\r
-\r
- Level += 1;\r
- Tables[Level] = TableEntry;\r
- Addresses[Level] = Address;\r
- Indices[Level] = 0;\r
+ Level += 1;\r
+ Tables[Level] = TableEntry;\r
+ Addresses[Level] = Address;\r
+ Indices[Level] = 0;\r
\r
continue;\r
-\r
} else {\r
-\r
Index = 0;\r
while (Index < GUARDED_HEAP_MAP_ENTRY_BITS) {\r
if ((TableEntry & 1) == 1) {\r
} else {\r
GuardPage = Address - EFI_PAGE_SIZE;\r
}\r
+\r
OnGuarding = TRUE;\r
} else {\r
if (OnGuarding) {\r
} else {\r
GuardPage = 0;\r
}\r
+\r
OnGuarding = FALSE;\r
}\r
\r
break;\r
}\r
\r
- Indices[Level] += 1;\r
- Address = (Level == 0) ? 0 : Addresses[Level - 1];\r
- Addresses[Level] = Address | LShiftU64(Indices[Level], Shifts[Level]);\r
+ Indices[Level] += 1;\r
+ Address = (Level == 0) ? 0 : Addresses[Level - 1];\r
+ Addresses[Level] = Address | LShiftU64 (Indices[Level], Shifts[Level]);\r
+ }\r
+}\r
+\r
+/**\r
+ Find the address of top-most guarded free page.\r
+\r
+ @param[out] Address Start address of top-most guarded free page.\r
\r
+ @return VOID.\r
+**/\r
+VOID\r
+GetLastGuardedFreePageAddress (\r
+ OUT EFI_PHYSICAL_ADDRESS *Address\r
+ )\r
+{\r
+ EFI_PHYSICAL_ADDRESS AddressGranularity;\r
+ EFI_PHYSICAL_ADDRESS BaseAddress;\r
+ UINTN Level;\r
+ UINT64 Map;\r
+ INTN Index;\r
+\r
+ ASSERT (mMapLevel >= 1);\r
+\r
+ BaseAddress = 0;\r
+ Map = mGuardedMemoryMap;\r
+ for (Level = GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel;\r
+ Level < GUARDED_HEAP_MAP_TABLE_DEPTH;\r
+ ++Level)\r
+ {\r
+ AddressGranularity = LShiftU64 (1, mLevelShift[Level]);\r
+\r
+ //\r
+ // Find the non-NULL entry at largest index.\r
+ //\r
+ for (Index = (INTN)mLevelMask[Level]; Index >= 0; --Index) {\r
+ if (((UINT64 *)(UINTN)Map)[Index] != 0) {\r
+ BaseAddress += MultU64x32 (AddressGranularity, (UINT32)Index);\r
+ Map = ((UINT64 *)(UINTN)Map)[Index];\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Find the non-zero MSB then get the page address.\r
+ //\r
+ while (Map != 0) {\r
+ Map = RShiftU64 (Map, 1);\r
+ BaseAddress += EFI_PAGES_TO_SIZE (1);\r
}\r
+\r
+ *Address = BaseAddress;\r
+}\r
+\r
+/**\r
+ Record freed pages.\r
+\r
+ @param[in] BaseAddress Base address of just freed pages.\r
+ @param[in] Pages Number of freed pages.\r
+\r
+ @return VOID.\r
+**/\r
+VOID\r
+MarkFreedPages (\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINTN Pages\r
+ )\r
+{\r
+ SetGuardedMemoryBits (BaseAddress, Pages);\r
+}\r
+\r
+/**\r
+ Record freed pages as well as mark them as not-present.\r
+\r
+ @param[in] BaseAddress Base address of just freed pages.\r
+ @param[in] Pages Number of freed pages.\r
+\r
+ @return VOID.\r
+**/\r
+VOID\r
+EFIAPI\r
+GuardFreedPages (\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINTN Pages\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Legacy memory lower than 1MB might be accessed with no allocation. Leave\r
+ // them alone.\r
+ //\r
+ if (BaseAddress < BASE_1MB) {\r
+ return;\r
+ }\r
+\r
+ MarkFreedPages (BaseAddress, Pages);\r
+ if (gCpu != NULL) {\r
+ //\r
+ // Set flag to make sure allocating memory without GUARD for page table\r
+ // operation; otherwise infinite loops could be caused.\r
+ //\r
+ mOnGuarding = TRUE;\r
+ //\r
+ // Note: This might overwrite other attributes needed by other features,\r
+ // such as NX memory protection.\r
+ //\r
+ Status = gCpu->SetMemoryAttributes (\r
+ gCpu,\r
+ BaseAddress,\r
+ EFI_PAGES_TO_SIZE (Pages),\r
+ EFI_MEMORY_RP\r
+ );\r
+ //\r
+ // Normally we should ASSERT the returned Status. But there might be memory\r
+ // alloc/free involved in SetMemoryAttributes(), which might fail this\r
+ // calling. It's rare case so it's OK to let a few tiny holes be not-guarded.\r
+ //\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_WARN, "Failed to guard freed pages: %p (%lu)\n", BaseAddress, (UINT64)Pages));\r
+ }\r
+\r
+ mOnGuarding = FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Record freed pages as well as mark them as not-present, if enabled.\r
+\r
+ @param[in] BaseAddress Base address of just freed pages.\r
+ @param[in] Pages Number of freed pages.\r
+\r
+ @return VOID.\r
+**/\r
+VOID\r
+EFIAPI\r
+GuardFreedPagesChecked (\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINTN Pages\r
+ )\r
+{\r
+ if (IsHeapGuardEnabled (GUARD_HEAP_TYPE_FREED)) {\r
+ GuardFreedPages (BaseAddress, Pages);\r
+ }\r
+}\r
+\r
+/**\r
+ Mark all pages freed before CPU Arch Protocol as not-present.\r
+\r
+**/\r
+VOID\r
+GuardAllFreedPages (\r
+ VOID\r
+ )\r
+{\r
+ UINTN Entries[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINTN Shifts[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINTN Indices[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINT64 Tables[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINT64 Addresses[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINT64 TableEntry;\r
+ UINT64 Address;\r
+ UINT64 GuardPage;\r
+ INTN Level;\r
+ UINT64 BitIndex;\r
+ UINTN GuardPageNumber;\r
+\r
+ if ((mGuardedMemoryMap == 0) ||\r
+ (mMapLevel == 0) ||\r
+ (mMapLevel > GUARDED_HEAP_MAP_TABLE_DEPTH))\r
+ {\r
+ return;\r
+ }\r
+\r
+ CopyMem (Entries, mLevelMask, sizeof (Entries));\r
+ CopyMem (Shifts, mLevelShift, sizeof (Shifts));\r
+\r
+ SetMem (Tables, sizeof (Tables), 0);\r
+ SetMem (Addresses, sizeof (Addresses), 0);\r
+ SetMem (Indices, sizeof (Indices), 0);\r
+\r
+ Level = GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel;\r
+ Tables[Level] = mGuardedMemoryMap;\r
+ Address = 0;\r
+ GuardPage = (UINT64)-1;\r
+ GuardPageNumber = 0;\r
+\r
+ while (TRUE) {\r
+ if (Indices[Level] > Entries[Level]) {\r
+ Tables[Level] = 0;\r
+ Level -= 1;\r
+ } else {\r
+ TableEntry = ((UINT64 *)(UINTN)(Tables[Level]))[Indices[Level]];\r
+ Address = Addresses[Level];\r
+\r
+ if (Level < GUARDED_HEAP_MAP_TABLE_DEPTH - 1) {\r
+ Level += 1;\r
+ Tables[Level] = TableEntry;\r
+ Addresses[Level] = Address;\r
+ Indices[Level] = 0;\r
+\r
+ continue;\r
+ } else {\r
+ BitIndex = 1;\r
+ while (BitIndex != 0) {\r
+ if ((TableEntry & BitIndex) != 0) {\r
+ if (GuardPage == (UINT64)-1) {\r
+ GuardPage = Address;\r
+ }\r
+\r
+ ++GuardPageNumber;\r
+ } else if (GuardPageNumber > 0) {\r
+ GuardFreedPages (GuardPage, GuardPageNumber);\r
+ GuardPageNumber = 0;\r
+ GuardPage = (UINT64)-1;\r
+ }\r
+\r
+ if (TableEntry == 0) {\r
+ break;\r
+ }\r
+\r
+ Address += EFI_PAGES_TO_SIZE (1);\r
+ BitIndex = LShiftU64 (BitIndex, 1);\r
+ }\r
+ }\r
+ }\r
+\r
+ if (Level < (GUARDED_HEAP_MAP_TABLE_DEPTH - (INTN)mMapLevel)) {\r
+ break;\r
+ }\r
+\r
+ Indices[Level] += 1;\r
+ Address = (Level == 0) ? 0 : Addresses[Level - 1];\r
+ Addresses[Level] = Address | LShiftU64 (Indices[Level], Shifts[Level]);\r
+ }\r
+\r
+ //\r
+ // Update the maximum address of freed page which can be used for memory\r
+ // promotion upon out-of-memory-space.\r
+ //\r
+ GetLastGuardedFreePageAddress (&Address);\r
+ if (Address != 0) {\r
+ mLastPromotedPage = Address;\r
+ }\r
+}\r
+\r
+/**\r
+ This function checks to see if the given memory map descriptor in a memory map\r
+ can be merged with any guarded free pages.\r
+\r
+ @param MemoryMapEntry A pointer to a descriptor in MemoryMap.\r
+ @param MaxAddress Maximum address to stop the merge.\r
+\r
+ @return VOID\r
+\r
+**/\r
+VOID\r
+MergeGuardPages (\r
+ IN EFI_MEMORY_DESCRIPTOR *MemoryMapEntry,\r
+ IN EFI_PHYSICAL_ADDRESS MaxAddress\r
+ )\r
+{\r
+ EFI_PHYSICAL_ADDRESS EndAddress;\r
+ UINT64 Bitmap;\r
+ INTN Pages;\r
+\r
+ if (!IsHeapGuardEnabled (GUARD_HEAP_TYPE_FREED) ||\r
+ (MemoryMapEntry->Type >= EfiMemoryMappedIO))\r
+ {\r
+ return;\r
+ }\r
+\r
+ Bitmap = 0;\r
+ Pages = EFI_SIZE_TO_PAGES ((UINTN)(MaxAddress - MemoryMapEntry->PhysicalStart));\r
+ Pages -= (INTN)MemoryMapEntry->NumberOfPages;\r
+ while (Pages > 0) {\r
+ if (Bitmap == 0) {\r
+ EndAddress = MemoryMapEntry->PhysicalStart +\r
+ EFI_PAGES_TO_SIZE ((UINTN)MemoryMapEntry->NumberOfPages);\r
+ Bitmap = GetGuardedMemoryBits (EndAddress, GUARDED_HEAP_MAP_ENTRY_BITS);\r
+ }\r
+\r
+ if ((Bitmap & 1) == 0) {\r
+ break;\r
+ }\r
+\r
+ Pages--;\r
+ MemoryMapEntry->NumberOfPages++;\r
+ Bitmap = RShiftU64 (Bitmap, 1);\r
+ }\r
+}\r
+\r
+/**\r
+ Put part (at most 64 pages a time) guarded free pages back to free page pool.\r
+\r
+ Freed memory guard is used to detect Use-After-Free (UAF) memory issue, which\r
+ makes use of 'Used then throw away' way to detect any illegal access to freed\r
+ memory. The thrown-away memory will be marked as not-present so that any access\r
+ to those memory (after free) will be caught by page-fault exception.\r
+\r
+ The problem is that this will consume lots of memory space. Once no memory\r
+ left in pool to allocate, we have to restore part of the freed pages to their\r
+ normal function. Otherwise the whole system will stop functioning.\r
+\r
+ @param StartAddress Start address of promoted memory.\r
+ @param EndAddress End address of promoted memory.\r
+\r
+ @return TRUE Succeeded to promote memory.\r
+ @return FALSE No free memory found.\r
+\r
+**/\r
+BOOLEAN\r
+PromoteGuardedFreePages (\r
+ OUT EFI_PHYSICAL_ADDRESS *StartAddress,\r
+ OUT EFI_PHYSICAL_ADDRESS *EndAddress\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN AvailablePages;\r
+ UINT64 Bitmap;\r
+ EFI_PHYSICAL_ADDRESS Start;\r
+\r
+ if (!IsHeapGuardEnabled (GUARD_HEAP_TYPE_FREED)) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Similar to memory allocation service, always search the freed pages in\r
+ // descending direction.\r
+ //\r
+ Start = mLastPromotedPage;\r
+ AvailablePages = 0;\r
+ while (AvailablePages == 0) {\r
+ Start -= EFI_PAGES_TO_SIZE (GUARDED_HEAP_MAP_ENTRY_BITS);\r
+ //\r
+ // If the address wraps around, try the really freed pages at top.\r
+ //\r
+ if (Start > mLastPromotedPage) {\r
+ GetLastGuardedFreePageAddress (&Start);\r
+ ASSERT (Start != 0);\r
+ Start -= EFI_PAGES_TO_SIZE (GUARDED_HEAP_MAP_ENTRY_BITS);\r
+ }\r
+\r
+ Bitmap = GetGuardedMemoryBits (Start, GUARDED_HEAP_MAP_ENTRY_BITS);\r
+ while (Bitmap > 0) {\r
+ if ((Bitmap & 1) != 0) {\r
+ ++AvailablePages;\r
+ } else if (AvailablePages == 0) {\r
+ Start += EFI_PAGES_TO_SIZE (1);\r
+ } else {\r
+ break;\r
+ }\r
+\r
+ Bitmap = RShiftU64 (Bitmap, 1);\r
+ }\r
+ }\r
+\r
+ if (AvailablePages != 0) {\r
+ DEBUG ((DEBUG_INFO, "Promoted pages: %lX (%lx)\r\n", Start, (UINT64)AvailablePages));\r
+ ClearGuardedMemoryBits (Start, AvailablePages);\r
+\r
+ if (gCpu != NULL) {\r
+ //\r
+ // Set flag to make sure allocating memory without GUARD for page table\r
+ // operation; otherwise infinite loops could be caused.\r
+ //\r
+ mOnGuarding = TRUE;\r
+ Status = gCpu->SetMemoryAttributes (gCpu, Start, EFI_PAGES_TO_SIZE (AvailablePages), 0);\r
+ ASSERT_EFI_ERROR (Status);\r
+ mOnGuarding = FALSE;\r
+ }\r
+\r
+ mLastPromotedPage = Start;\r
+ *StartAddress = Start;\r
+ *EndAddress = Start + EFI_PAGES_TO_SIZE (AvailablePages) - 1;\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
}\r
\r
/**\r
)\r
{\r
ASSERT (gCpu != NULL);\r
- SetAllGuardPages ();\r
+\r
+ if (IsHeapGuardEnabled (GUARD_HEAP_TYPE_PAGE|GUARD_HEAP_TYPE_POOL) &&\r
+ IsHeapGuardEnabled (GUARD_HEAP_TYPE_FREED))\r
+ {\r
+ DEBUG ((DEBUG_ERROR, "Heap guard and freed memory guard cannot be enabled at the same time.\n"));\r
+ CpuDeadLoop ();\r
+ }\r
+\r
+ if (IsHeapGuardEnabled (GUARD_HEAP_TYPE_PAGE|GUARD_HEAP_TYPE_POOL)) {\r
+ SetAllGuardPages ();\r
+ }\r
+\r
+ if (IsHeapGuardEnabled (GUARD_HEAP_TYPE_FREED)) {\r
+ GuardAllFreedPages ();\r
+ }\r
}\r
\r
/**\r
**/\r
VOID\r
Uint64ToBinString (\r
- IN UINT64 Value,\r
- OUT CHAR8 *BinString\r
+ IN UINT64 Value,\r
+ OUT CHAR8 *BinString\r
)\r
{\r
- UINTN Index;\r
+ UINTN Index;\r
\r
if (BinString == NULL) {\r
return;\r
\r
for (Index = 64; Index > 0; --Index) {\r
BinString[Index - 1] = '0' + (Value & 1);\r
- Value = RShiftU64 (Value, 1);\r
+ Value = RShiftU64 (Value, 1);\r
}\r
+\r
BinString[64] = '\0';\r
}\r
\r
VOID\r
)\r
{\r
- UINTN Entries[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
- UINTN Shifts[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
- UINTN Indices[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
- UINT64 Tables[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
- UINT64 Addresses[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
- UINT64 TableEntry;\r
- UINT64 Address;\r
- INTN Level;\r
- UINTN RepeatZero;\r
- CHAR8 String[GUARDED_HEAP_MAP_ENTRY_BITS + 1];\r
- CHAR8 *Ruler1;\r
- CHAR8 *Ruler2;\r
-\r
- if (mGuardedMemoryMap == 0 ||\r
- mMapLevel == 0 ||\r
- mMapLevel > GUARDED_HEAP_MAP_TABLE_DEPTH) {\r
+ UINTN Entries[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINTN Shifts[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINTN Indices[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINT64 Tables[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINT64 Addresses[GUARDED_HEAP_MAP_TABLE_DEPTH];\r
+ UINT64 TableEntry;\r
+ UINT64 Address;\r
+ INTN Level;\r
+ UINTN RepeatZero;\r
+ CHAR8 String[GUARDED_HEAP_MAP_ENTRY_BITS + 1];\r
+ CHAR8 *Ruler1;\r
+ CHAR8 *Ruler2;\r
+\r
+ if (!IsHeapGuardEnabled (GUARD_HEAP_TYPE_ALL)) {\r
+ return;\r
+ }\r
+\r
+ if ((mGuardedMemoryMap == 0) ||\r
+ (mMapLevel == 0) ||\r
+ (mMapLevel > GUARDED_HEAP_MAP_TABLE_DEPTH))\r
+ {\r
return;\r
}\r
\r
Ruler1 = " 3 2 1 0";\r
Ruler2 = "FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210";\r
\r
- DEBUG ((HEAP_GUARD_DEBUG_LEVEL, "============================="\r
- " Guarded Memory Bitmap "\r
- "==============================\r\n"));\r
+ DEBUG ((\r
+ HEAP_GUARD_DEBUG_LEVEL,\r
+ "============================="\r
+ " Guarded Memory Bitmap "\r
+ "==============================\r\n"\r
+ ));\r
DEBUG ((HEAP_GUARD_DEBUG_LEVEL, " %a\r\n", Ruler1));\r
DEBUG ((HEAP_GUARD_DEBUG_LEVEL, " %a\r\n", Ruler2));\r
\r
CopyMem (Entries, mLevelMask, sizeof (Entries));\r
CopyMem (Shifts, mLevelShift, sizeof (Shifts));\r
\r
- SetMem (Indices, sizeof(Indices), 0);\r
- SetMem (Tables, sizeof(Tables), 0);\r
- SetMem (Addresses, sizeof(Addresses), 0);\r
+ SetMem (Indices, sizeof (Indices), 0);\r
+ SetMem (Tables, sizeof (Tables), 0);\r
+ SetMem (Addresses, sizeof (Addresses), 0);\r
\r
Level = GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel;\r
Tables[Level] = mGuardedMemoryMap;\r
\r
while (TRUE) {\r
if (Indices[Level] > Entries[Level]) {\r
-\r
Tables[Level] = 0;\r
Level -= 1;\r
RepeatZero = 0;\r
"========================================="\r
"=========================================\r\n"\r
));\r
-\r
} else {\r
-\r
- TableEntry = ((UINT64 *)(UINTN)Tables[Level])[Indices[Level]];\r
- Address = Addresses[Level];\r
+ TableEntry = ((UINT64 *)(UINTN)Tables[Level])[Indices[Level]];\r
+ Address = Addresses[Level];\r
\r
if (TableEntry == 0) {\r
-\r
if (Level == GUARDED_HEAP_MAP_TABLE_DEPTH - 1) {\r
if (RepeatZero == 0) {\r
- Uint64ToBinString(TableEntry, String);\r
+ Uint64ToBinString (TableEntry, String);\r
DEBUG ((HEAP_GUARD_DEBUG_LEVEL, "%016lx: %a\r\n", Address, String));\r
} else if (RepeatZero == 1) {\r
DEBUG ((HEAP_GUARD_DEBUG_LEVEL, "... : ...\r\n"));\r
}\r
+\r
RepeatZero += 1;\r
}\r
-\r
} else if (Level < GUARDED_HEAP_MAP_TABLE_DEPTH - 1) {\r
-\r
- Level += 1;\r
- Tables[Level] = TableEntry;\r
- Addresses[Level] = Address;\r
- Indices[Level] = 0;\r
- RepeatZero = 0;\r
+ Level += 1;\r
+ Tables[Level] = TableEntry;\r
+ Addresses[Level] = Address;\r
+ Indices[Level] = 0;\r
+ RepeatZero = 0;\r
\r
continue;\r
-\r
} else {\r
-\r
RepeatZero = 0;\r
- Uint64ToBinString(TableEntry, String);\r
+ Uint64ToBinString (TableEntry, String);\r
DEBUG ((HEAP_GUARD_DEBUG_LEVEL, "%016lx: %a\r\n", Address, String));\r
-\r
}\r
}\r
\r
break;\r
}\r
\r
- Indices[Level] += 1;\r
- Address = (Level == 0) ? 0 : Addresses[Level - 1];\r
- Addresses[Level] = Address | LShiftU64(Indices[Level], Shifts[Level]);\r
-\r
+ Indices[Level] += 1;\r
+ Address = (Level == 0) ? 0 : Addresses[Level - 1];\r
+ Addresses[Level] = Address | LShiftU64 (Indices[Level], Shifts[Level]);\r
}\r
}\r
-\r