]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg/ArmMmuLib AARCH64: limit recursion when freeing page tables
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Wed, 25 Mar 2020 14:54:09 +0000 (15:54 +0100)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 26 Mar 2020 10:34:14 +0000 (10:34 +0000)
FreePageTablesRecursive () traverses the page table tree depth first
to free all pages that it finds, without taking into account the
level at which it is operating.

Since TT_TYPE_TABLE_ENTRY aliases TT_TYPE_BLOCK_ENTRY_LEVEL3, we cannot
distinguish table entries from block entries unless we take the level
into account, and so we may be dereferencing garbage if we happen to
try and free a hierarchy of page tables that has level 3 pages in it.

Let's fix this by passing the level into FreePageTablesRecursive (),
and limit the recursion to levels < 3.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif@nuviainc.com>
Reviewed-by: Ashish Singhal <ashishsingha@nvidia.com>
Tested-by: Ashish Singhal <ashishsingha@nvidia.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c

index a43d468b73ca72adb9af58412a52c32cbbd9e992..d78918cf7ba80f0c0837aaddfee50b78fa2b36e6 100644 (file)
@@ -142,15 +142,21 @@ ReplaceTableEntry (
 STATIC\r
 VOID\r
 FreePageTablesRecursive (\r
-  IN  UINT64  *TranslationTable\r
+  IN  UINT64  *TranslationTable,\r
+  IN  UINTN   Level\r
   )\r
 {\r
   UINTN   Index;\r
 \r
-  for (Index = 0; Index < TT_ENTRY_COUNT; Index++) {\r
-    if ((TranslationTable[Index] & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {\r
-      FreePageTablesRecursive ((VOID *)(UINTN)(TranslationTable[Index] &\r
-                                               TT_ADDRESS_MASK_BLOCK_ENTRY));\r
+  ASSERT (Level <= 3);\r
+\r
+  if (Level < 3) {\r
+    for (Index = 0; Index < TT_ENTRY_COUNT; Index++) {\r
+      if ((TranslationTable[Index] & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {\r
+        FreePageTablesRecursive ((VOID *)(UINTN)(TranslationTable[Index] &\r
+                                                 TT_ADDRESS_MASK_BLOCK_ENTRY),\r
+                                 Level + 1);\r
+      }\r
     }\r
   }\r
   FreePages (TranslationTable, 1);\r
@@ -254,7 +260,7 @@ UpdateRegionMappingRecursive (
           // possible for existing table entries, since we cannot revert the\r
           // modifications we made to the subhierarchy it represents.)\r
           //\r
-          FreePageTablesRecursive (TranslationTable);\r
+          FreePageTablesRecursive (TranslationTable, Level + 1);\r
         }\r
         return Status;\r
       }\r