Skip to contentSkip to conversation

arm64/mm: Sanity check PTE address before runtime P4D/PUD folding

PATCH Applied Ard Biesheuvel 2 participants 2 messages Nov 5, 2024 arm64

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 arm64/mm: Sanity check PTE address before runtime P4D/PUD folding

From: Ard Biesheuvel <[email protected]>

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/[email protected]/T/#u

---
v2: drop complicated logic and static inline helper

 arch/arm64/include/asm/pgtable.h | 6 ++++++
 1 file changed, 6 insertions(+)
arch/arm64/include/asm/pgtable.h +6 -0
index dd5dcf7ae056..b76603618716 100644
@@ -932,6 +932,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);
 }
 
@@ -1056,6 +1059,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);
 }
 
Signature · 1 line
2.47.0.199.ga7371fff76-goog
maintainer Applied
#1 lore raw
Quoted 9 lines · Ard Biesheuvel

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.

[...]

Applied to arm64 (for-next/misc), thanks!

Easier to read now ;).

[1/1] arm64/mm: Sanity check PTE address before runtime P4D/PUD folding

      https://git.kernel.org/arm64/c/baec23979719
Signature · 1 line
Catalin