summaryrefslogtreecommitdiffstats
path: root/ArmPkg
diff options
context:
space:
mode:
authorHeyi Guo <heyi.guo@linaro.org>2015-09-09 13:37:50 +0000
committerabiesheuvel <abiesheuvel@Edk2>2015-09-09 13:37:50 +0000
commit8483681426b5a33e9d186758c47def0f1fcd86e2 (patch)
tree49f96c6333807d7d68152af461fa8436eb9a00ae /ArmPkg
parentedff645fe4d8a815618b41a9285e2da6ea7f1257 (diff)
downloadedk2-8483681426b5a33e9d186758c47def0f1fcd86e2.tar.gz
edk2-8483681426b5a33e9d186758c47def0f1fcd86e2.tar.bz2
edk2-8483681426b5a33e9d186758c47def0f1fcd86e2.zip
ArmPkg/Mmu: Fix potential page table memory leak
During page entry attribute update, if there are table entries between starting BlockEntry and LastBlockEntry, table entries will be set as block entries and the allocated memory of the tables will be leaked. So instead, we break the inner loop when we find a table entry and run outer loop again to step into the table by the same logic. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Heyi Guo <heyi.guo@linaro.org> Cc: Leif Lindholm <leif.lindholm@linaro.org> [ardb: move termination condition check inside the loop] Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18425 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPkg')
-rw-r--r--ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
index 850fe7ff14..df37154f35 100644
--- a/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
+++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Mmu.c
@@ -455,6 +455,13 @@ FillTranslationTable (
RegionStart += BlockEntrySize;
RemainingRegionLength -= BlockEntrySize;
BlockEntry++;
+
+ // Break the inner loop when next block is a table
+ // Rerun GetBlockEntryListFromAddress to avoid page table memory leak
+ if (TableLevel != 3 &&
+ (*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {
+ break;
+ }
} while ((RemainingRegionLength >= BlockEntrySize) && (BlockEntry <= LastBlockEntry));
} while (RemainingRegionLength != 0);