X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FCore%2FPiSmmCore%2FHeapGuard.c;h=d5556eb79cb1cfd73ba1569fe8c9e2ee02708cbb;hp=04fa1747a1e15ea9397ee85762744d951b163f8a;hb=a2f32ef6ff173ef276a661520196fb04bbaec3f9;hpb=38d870fc4e9b5a1896c98d12947713fb7b4b9ac4 diff --git a/MdeModulePkg/Core/PiSmmCore/HeapGuard.c b/MdeModulePkg/Core/PiSmmCore/HeapGuard.c index 04fa1747a1..d5556eb79c 100644 --- a/MdeModulePkg/Core/PiSmmCore/HeapGuard.c +++ b/MdeModulePkg/Core/PiSmmCore/HeapGuard.c @@ -1,7 +1,7 @@ /** @file UEFI Heap Guard functions. -Copyright (c) 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2017-2018, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -73,7 +73,7 @@ SetBits ( StartBit = (UINTN)GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address); EndBit = (StartBit + BitNumber - 1) % GUARDED_HEAP_MAP_ENTRY_BITS; - if ((StartBit + BitNumber) > GUARDED_HEAP_MAP_ENTRY_BITS) { + if ((StartBit + BitNumber) >= GUARDED_HEAP_MAP_ENTRY_BITS) { Msbs = (GUARDED_HEAP_MAP_ENTRY_BITS - StartBit) % GUARDED_HEAP_MAP_ENTRY_BITS; Lsbs = (EndBit + 1) % GUARDED_HEAP_MAP_ENTRY_BITS; @@ -126,7 +126,7 @@ ClearBits ( StartBit = (UINTN)GUARDED_HEAP_MAP_ENTRY_BIT_INDEX (Address); EndBit = (StartBit + BitNumber - 1) % GUARDED_HEAP_MAP_ENTRY_BITS; - if ((StartBit + BitNumber) > GUARDED_HEAP_MAP_ENTRY_BITS) { + if ((StartBit + BitNumber) >= GUARDED_HEAP_MAP_ENTRY_BITS) { Msbs = (GUARDED_HEAP_MAP_ENTRY_BITS - StartBit) % GUARDED_HEAP_MAP_ENTRY_BITS; Lsbs = (EndBit + 1) % GUARDED_HEAP_MAP_ENTRY_BITS; @@ -191,10 +191,14 @@ GetBits ( Lsbs = 0; } - Result = RShiftU64 ((*BitMap), StartBit) & (LShiftU64 (1, Msbs) - 1); - if (Lsbs > 0) { - BitMap += 1; - Result |= LShiftU64 ((*BitMap) & (LShiftU64 (1, Lsbs) - 1), Msbs); + if (StartBit == 0 && BitNumber == GUARDED_HEAP_MAP_ENTRY_BITS) { + Result = *BitMap; + } else { + Result = RShiftU64((*BitMap), StartBit) & (LShiftU64(1, Msbs) - 1); + if (Lsbs > 0) { + BitMap += 1; + Result |= LShiftU64 ((*BitMap) & (LShiftU64 (1, Lsbs) - 1), Msbs); + } } return Result; @@ -251,8 +255,8 @@ FindGuardedMemoryMap ( // // Adjust current map table depth according to the address to access // - while (mMapLevel < GUARDED_HEAP_MAP_TABLE_DEPTH - && + while (AllocMapUnit && + mMapLevel < GUARDED_HEAP_MAP_TABLE_DEPTH && RShiftU64 ( Address, mLevelShift[GUARDED_HEAP_MAP_TABLE_DEPTH - mMapLevel - 1] @@ -877,12 +881,18 @@ AdjustMemoryS ( { UINT64 Target; - Target = Start + Size - SizeRequested; - // - // At least one more page needed for Guard page. + // UEFI spec requires that allocated pool must be 8-byte aligned. If it's + // indicated to put the pool near the Tail Guard, we need extra bytes to + // make sure alignment of the returned pool address. // - if (Size < (SizeRequested + EFI_PAGES_TO_SIZE (1))) { + if ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) == 0) { + SizeRequested = ALIGN_VALUE(SizeRequested, 8); + } + + Target = Start + Size - SizeRequested; + ASSERT (Target >= Start); + if (Target == 0) { return 0; } @@ -931,6 +941,7 @@ AdjustMemoryF ( EFI_PHYSICAL_ADDRESS MemoryToTest; UINTN PagesToFree; UINT64 GuardBitmap; + UINT64 Attributes; if (Memory == NULL || NumberOfPages == NULL || *NumberOfPages == 0) { return; @@ -939,6 +950,27 @@ AdjustMemoryF ( Start = *Memory; PagesToFree = *NumberOfPages; + // + // In case the memory to free is marked as read-only (e.g. EfiRuntimeServicesCode). + // + if (mSmmMemoryAttribute != NULL) { + Attributes = 0; + mSmmMemoryAttribute->GetMemoryAttributes ( + mSmmMemoryAttribute, + Start, + EFI_PAGES_TO_SIZE (PagesToFree), + &Attributes + ); + if ((Attributes & EFI_MEMORY_RO) != 0) { + mSmmMemoryAttribute->ClearMemoryAttributes ( + mSmmMemoryAttribute, + Start, + EFI_PAGES_TO_SIZE (PagesToFree), + EFI_MEMORY_RO + ); + } + } + // // Head Guard must be one page before, if any. // @@ -1060,7 +1092,7 @@ AdjustPoolHeadA ( IN UINTN Size ) { - if ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0) { + if (Memory == 0 || (PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0) { // // Pool head is put near the head Guard // @@ -1070,6 +1102,7 @@ AdjustPoolHeadA ( // // Pool head is put near the tail Guard // + Size = ALIGN_VALUE (Size, 8); return (VOID *)(UINTN)(Memory + EFI_PAGES_TO_SIZE (NoPages) - Size); } @@ -1085,7 +1118,7 @@ AdjustPoolHeadF ( IN EFI_PHYSICAL_ADDRESS Memory ) { - if ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0) { + if (Memory == 0 || (PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0) { // // Pool head is put near the head Guard // @@ -1195,6 +1228,10 @@ SmmInternalFreePagesExWithGuard ( EFI_PHYSICAL_ADDRESS MemoryToFree; UINTN PagesToFree; + if (((Memory & EFI_PAGE_MASK) != 0) || (Memory == 0) || (NumberOfPages == 0)) { + return EFI_INVALID_PARAMETER; + } + MemoryToFree = Memory; PagesToFree = NumberOfPages;