From: Alejandro Jimenez <[email protected]>

The AMD-Vi specification requires that the NextLevel field for a page table
entry must not be greater or equal to the current page table entry level.
Enforce this to avoid infinite page walk loops on corrupted or buggy guest
page tables.

The initial implementation of fetch_pte() did not implement this check, but
was not vulnerable since the page walk code explicitly decremented the level
instead of retrieving it from the page table entry.

Cc: [email protected]
Reviewed-by: Sairaj Kodilkar <[email protected]>
Signed-off-by: Alejandro Jimenez <[email protected]>
Reviewed-by: Michael S. Tsirkin <[email protected]>
Signed-off-by: Michael S. Tsirkin <[email protected]>
Message-Id: <[email protected]>
(cherry picked from commit 291aa70ad254b6c48012dbfd16a4af0978ea1b84)
Signed-off-by: Michael Tokarev <[email protected]>

diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index 86dab42624..a7991b2790 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -771,6 +771,10 @@ static uint64_t fetch_pte(AMDVIAddressSpace *as, hwaddr 
address, uint64_t dte,
             break;
         }
 
+        /* Next level must always be less than current level */
+        if (pt_level <= next_pt_level) {
+            return -AMDVI_FR_PT_ENTRY_INV;
+        }
         pt_level = next_pt_level;
 
         /*
-- 
2.47.3


Reply via email to