summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg
diff options
context:
space:
mode:
authorDun Tan <dun.tan@intel.com>2024-10-10 15:38:09 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-10-30 05:48:24 +0000
commit004232c6af01a2de60a9c37da89985af00b53624 (patch)
tree033a73299584df53cb9bfb86bd178c489fe3eb3f /UefiCpuPkg
parentacce74762b45f26adb461ef46de4bf8e2d722e94 (diff)
downloadedk2-004232c6af01a2de60a9c37da89985af00b53624.tar.gz
edk2-004232c6af01a2de60a9c37da89985af00b53624.tar.bz2
edk2-004232c6af01a2de60a9c37da89985af00b53624.zip
UefiCpuPkg/MmUnblockMemoryLib: Check if buffer range is valid
Check if input buffer range unblockable: 1.The input buffer range to block should be totally covered by one or multi memory allocation HOB 2.All the memory allocation HOB that overlap with the input buffer range should be EfiRuntimeServicesData, EfiACPIMemoryNVS or EfiReservedMemoryType. Signed-off-by: Dun Tan <dun.tan@intel.com>
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r--UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.c b/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.c
index 790392b19d..c42ca106eb 100644
--- a/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.c
+++ b/UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.c
@@ -18,6 +18,85 @@
#include <Library/BaseMemoryLib.h>
#include <Library/PeiServicesLib.h>
#include <Base.h>
+#include <PiPei.h>
+
+/**
+ This function checks if the input buffer range [UnblockBase, UnblockEnd] is unblockable.
+ The input range should be covered by the EfiRuntimeServicesData, EfiACPIMemoryNVS or
+ EfiReservedMemoryType memory allocation HOB.
+
+ @param[in] HobStart The starting HOB pointer to search from.
+ @param[in] UnblockAddress Base address of the range to unblock.
+ @param[in] UnblockEnd End address of the range to unblock.
+
+ @retval RETURN_SUCCESS The range is unblockable.
+ @retval RETURN_INVALID_PARAMETER The range to unblock contains invalid memory.
+**/
+EFI_STATUS
+MmUnblockMemoryLibIsUnblockableRegion (
+ IN VOID *HobStart,
+ IN EFI_PHYSICAL_ADDRESS UnblockBase,
+ IN EFI_PHYSICAL_ADDRESS UnblockEnd
+ )
+{
+ EFI_PHYSICAL_ADDRESS HobBase;
+ EFI_PHYSICAL_ADDRESS HobEnd;
+ EFI_STATUS Status;
+ EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob;
+
+ while ((MemoryAllocationHob = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, HobStart)) != NULL) {
+ HobBase = MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress;
+ HobEnd = MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress +
+ MemoryAllocationHob->AllocDescriptor.MemoryLength;
+ if ((UnblockBase < HobEnd) && (UnblockEnd > HobBase)) {
+ //
+ // The overlapped memory allocation HOB type must be one of the three specific types.
+ //
+ if ((MemoryAllocationHob->AllocDescriptor.MemoryType != EfiRuntimeServicesData) &&
+ (MemoryAllocationHob->AllocDescriptor.MemoryType != EfiACPIMemoryNVS) &&
+ (MemoryAllocationHob->AllocDescriptor.MemoryType != EfiReservedMemoryType))
+ {
+ DEBUG ((DEBUG_ERROR, "Error: range [0x%lx, 0x%lx] to unblock contains invalid type memory\n", UnblockBase, UnblockEnd));
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ if (UnblockBase < HobBase) {
+ //
+ // Recursively call to check [UnblockBase, HobBase]
+ //
+ Status = MmUnblockMemoryLibIsUnblockableRegion (
+ GET_NEXT_HOB (MemoryAllocationHob),
+ UnblockBase,
+ HobBase
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ if (UnblockEnd > HobEnd) {
+ //
+ // Recursively call to check [HobEnd, UnblockEnd]
+ //
+ Status = MmUnblockMemoryLibIsUnblockableRegion (
+ GET_NEXT_HOB (MemoryAllocationHob),
+ HobEnd,
+ UnblockEnd
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ HobStart = GET_NEXT_HOB (MemoryAllocationHob);
+ }
+
+ DEBUG ((DEBUG_ERROR, "Error: range [0x%lx, 0x%lx] to unblock doesn't belong to any memory allocation HOB\n", UnblockBase, UnblockEnd));
+ return RETURN_INVALID_PARAMETER;
+}
/**
This API provides a way to unblock certain data pages to be accessible inside MM environment.
@@ -32,6 +111,10 @@
@retval RETURN_SECURITY_VIOLATION The requested address failed to pass security check for
unblocking.
@retval RETURN_INVALID_PARAMETER Input address either NULL pointer or not page aligned.
+ @retval RETURN_INVALID_PARAMETER Input range to unblock contains invalid types memory other than
+ EfiRuntimeServicesData, EfiACPIMemoryNVS, and EfiReservedMemory.
+ @retval RETURN_INVALID_PARAMETER Input range to unblock contains memory that doesn't belong to
+ any memory allocation HOB.
@retval RETURN_ACCESS_DENIED The request is rejected due to system has passed certain boot
phase.
**/
@@ -45,12 +128,19 @@ MmUnblockMemoryRequest (
EFI_STATUS Status;
MM_UNBLOCK_REGION *MmUnblockMemoryHob;
EFI_PEI_MM_COMMUNICATION_PPI *MmCommunicationPpi;
+ VOID *HobList;
if (!IS_ALIGNED (UnblockAddress, SIZE_4KB)) {
DEBUG ((DEBUG_ERROR, "Error: UnblockAddress is not 4KB aligned: %p\n", UnblockAddress));
return EFI_INVALID_PARAMETER;
}
+ HobList = GetHobList ();
+ Status = MmUnblockMemoryLibIsUnblockableRegion (HobList, UnblockAddress, UnblockAddress + EFI_PAGES_TO_SIZE (NumberOfPages));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
//
// Unblock requests are rejected when MmIpl finishes execution.
//