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