]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
arm64/mm: Sanity check PTE address before runtime P4D/PUD folding
authorArd Biesheuvel <ardb@kernel.org>
Tue, 5 Nov 2024 09:39:20 +0000 (10:39 +0100)
committerCatalin Marinas <catalin.marinas@arm.com>
Tue, 5 Nov 2024 11:48:58 +0000 (11:48 +0000)
The runtime P4D/PUD folding logic assumes that the respective pgd_t* and
p4d_t* arguments are pointers into actual page tables that are part of
the hierarchy being operated on.

This may not always be the case, and we have been bitten once by this
already [0], where the argument was actually a stack variable, and in
this case, the logic does not work at all.

So let's add a VM_BUG_ON() for each case, to ensure that the address of
the provided page table entry is consistent with the address being
translated.

[0] https://lore.kernel.org/all/20240725090345.28461-1-will@kernel.org/T/#u

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20241105093919.1312049-2-ardb+git@google.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/include/asm/pgtable.h

index 0569b2308fd125321ec78dfd7e940f58eaec752d..073e25f734458183ecc4a12a210a369e1d3c27e9 100644 (file)
@@ -921,6 +921,9 @@ static inline phys_addr_t p4d_page_paddr(p4d_t p4d)
 
 static inline pud_t *p4d_to_folded_pud(p4d_t *p4dp, unsigned long addr)
 {
+       /* Ensure that 'p4dp' indexes a page table according to 'addr' */
+       VM_BUG_ON(((addr >> P4D_SHIFT) ^ ((u64)p4dp >> 3)) % PTRS_PER_P4D);
+
        return (pud_t *)PTR_ALIGN_DOWN(p4dp, PAGE_SIZE) + pud_index(addr);
 }
 
@@ -1045,6 +1048,9 @@ static inline phys_addr_t pgd_page_paddr(pgd_t pgd)
 
 static inline p4d_t *pgd_to_folded_p4d(pgd_t *pgdp, unsigned long addr)
 {
+       /* Ensure that 'pgdp' indexes a page table according to 'addr' */
+       VM_BUG_ON(((addr >> PGDIR_SHIFT) ^ ((u64)pgdp >> 3)) % PTRS_PER_PGD);
+
        return (p4d_t *)PTR_ALIGN_DOWN(pgdp, PAGE_SIZE) + p4d_index(addr);
 }