The UAF (Use-After-Free) memory detection feature will cause an
infinite calling of InitializePageTablePool(). This is due to a
fact that AllocateAlignedPages() is used to allocate page table
pool memory. This function will most likely call gBS->FreePages
to free unaligned pages and then cause another round of page
attributes change, like below

   FreePages() <===============|
=> SetMemoryAttributes()       |
=> <out of page table>         |
=> InitializePageTablePool()   |
=> AllocateAlignedPages()      |
=> FreePages() ================|

The solution is add a lock in page table pool allocation function
and fail any other requests if it has not been done.

Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Michael D Kinney <michael.d.kin...@intel.com>
Cc: Jiewen Yao <jiewen....@intel.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jian J Wang <jian.j.w...@intel.com>
---
 UefiCpuPkg/CpuDxe/CpuPageTable.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/UefiCpuPkg/CpuDxe/CpuPageTable.c b/UefiCpuPkg/CpuDxe/CpuPageTable.c
index 33e8ee2d2c..2145e623fa 100644
--- a/UefiCpuPkg/CpuDxe/CpuPageTable.c
+++ b/UefiCpuPkg/CpuDxe/CpuPageTable.c
@@ -100,6 +100,7 @@ PAGE_ATTRIBUTE_TABLE mPageAttributeTable[] = {
 };
 
 PAGE_TABLE_POOL                   *mPageTablePool = NULL;
+EFI_LOCK                          mPageTablePoolLock = 
EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
 PAGE_TABLE_LIB_PAGING_CONTEXT     mPagingContext;
 EFI_SMM_BASE2_PROTOCOL            *mSmmBase2 = NULL;
 
@@ -1045,6 +1046,12 @@ InitializePageTablePool (
 {
   VOID                      *Buffer;
   BOOLEAN                   IsModified;
+  EFI_STATUS                Status;
+
+  Status = EfiAcquireLockOrFail (&mPageTablePoolLock);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
 
   //
   // Always reserve at least PAGE_TABLE_POOL_UNIT_PAGES, including one page for
@@ -1056,7 +1063,10 @@ InitializePageTablePool (
   Buffer = AllocateAlignedPages (PoolPages, PAGE_TABLE_POOL_ALIGNMENT);
   if (Buffer == NULL) {
     DEBUG ((DEBUG_ERROR, "ERROR: Out of aligned pages\r\n"));
+    EfiReleaseLock (&mPageTablePoolLock);
     return FALSE;
+  } else {
+    DEBUG ((DEBUG_INFO, "Paging: added %d pages to page table pool\r\n", 
PoolPages));
   }
 
   //
@@ -1092,6 +1102,8 @@ InitializePageTablePool (
     );
   ASSERT (IsModified == TRUE);
 
+  EfiReleaseLock (&mPageTablePoolLock);
+
   return TRUE;
 }
 
-- 
2.16.2.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to