From f965b772fcc4bdc5f207998126d93d80c085d5f5 Mon Sep 17 00:00:00 2001
From: Eric Dong <eric.dong@intel.com>
Date: Tue, 21 Aug 2018 14:44:41 +0800
Subject: [PATCH] MdeModulePkg/PiSmmCore: Check valid memory range.

Call BS.AllocatePages in DXE driver and call SMM FreePages with the address of the buffer allocated in the DXE driver. SMM FreePages success and add a non-SMRAM range into SMM heap list. This is not an expected behavior. SMM FreePages should return error for this case and not free the pages.

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=1098

Change-Id: Ie5ffa1ac62c558aa418a8a3d7d0e8158b846e13b
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
---
 MdeModulePkg/Core/PiSmmCore/Page.c | 39 ++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/MdeModulePkg/Core/PiSmmCore/Page.c b/MdeModulePkg/Core/PiSmmCore/Page.c
index cd7d7ece0c..25f72d309b 100644
--- a/MdeModulePkg/Core/PiSmmCore/Page.c
+++ b/MdeModulePkg/Core/PiSmmCore/Page.c
@@ -862,6 +862,41 @@ SmmInternalFreePages (
   return SmmInternalFreePagesEx (Memory, NumberOfPages, FALSE);
 }
 
+/**
+  Check whether the input range is in memory map.
+
+  @param  Memory                 Base address of memory being inputed.
+  @param  NumberOfPages          The number of pages.
+
+  @retval TRUE   In memory map.
+  @retval FALSE  Not in memory map.
+
+**/
+BOOLEAN
+InMemMap (
+  IN EFI_PHYSICAL_ADDRESS  Memory,
+  IN UINTN                 NumberOfPages
+  )
+{
+  LIST_ENTRY               *Link;
+  MEMORY_MAP               *Entry;
+  EFI_PHYSICAL_ADDRESS     Last;
+
+  Last = Memory + EFI_PAGES_TO_SIZE (NumberOfPages) - 1;
+
+  Link = gMemoryMap.ForwardLink;
+  while (Link != &gMemoryMap) {
+    Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+    Link  = Link->ForwardLink;
+
+    if ((Entry->Start <= Memory) && (Entry->End >= Last)) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
 /**
   Frees previous allocated pages.
 
@@ -883,6 +918,10 @@ SmmFreePages (
   EFI_STATUS  Status;
   BOOLEAN     IsGuarded;
 
+  if (!InMemMap(Memory, NumberOfPages)) {
+    return EFI_NOT_FOUND;
+  }
+
   IsGuarded = IsHeapGuardEnabled () && IsMemoryGuarded (Memory);
   Status = SmmInternalFreePages (Memory, NumberOfPages, IsGuarded);
   if (!EFI_ERROR (Status)) {