[RFC PATCH v2 4/4] arm64: mm: Move fixmap intermediate page tables into .rodata
From: Ard Biesheuvel
Date: Thu Aug 27 2026 - 12:46:38 EST
From: Ard Biesheuvel <ardb@xxxxxxxxxx>
The fixmap intermediate page tables are allocated statically, are
installed into the kernel's page table hierarchy early during boot, and
control a slice of the kernel's virtual address space that is not
subject to KASLR randomization.
Combined with the lack of randomization of the linear map, and the
tendency of some Android bootloaders to place the kernel image at the
base of DRAM in the physical space, the placement of these page tables
produces a vulnerability that is comparatively easy to exploit.
Avoid this, by moving these intermediate page tables into .rodata, so
that they cannot be manipulated directly via the linear map.
Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx>
---
arch/arm64/include/asm/linkage.h | 1 +
arch/arm64/mm/fixmap.c | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h
index d1f7a16729d2..00963e11ebf0 100644
--- a/arch/arm64/include/asm/linkage.h
+++ b/arch/arm64/include/asm/linkage.h
@@ -45,6 +45,7 @@
#define _THIS_IP_ ({ unsigned long __ip; asm volatile("adr %0, ." : "=r" (__ip)); __ip; })
+#define __rodata_pgtbl __section(".pgtbl.ro_after_init") __aligned(PAGE_SIZE)
#define __bss_pgtbl __section(".bss..pgtbl") __aligned(PAGE_SIZE)
#endif
diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c
index 3a8cf6de6a7d..ab0f9ba7b712 100644
--- a/arch/arm64/mm/fixmap.c
+++ b/arch/arm64/mm/fixmap.c
@@ -32,8 +32,8 @@ static_assert(NR_BM_PMD_TABLES == 1);
#define BM_PTE_TABLE_IDX(addr) __BM_TABLE_IDX(addr, PMD_SHIFT)
pte_t fixmap_bm_pte[NR_BM_PTE_TABLES][PTRS_PER_PTE] __bss_pgtbl;
-static pmd_t bm_pmd[PTRS_PER_PMD] __bss_pgtbl __maybe_unused;
-static pud_t bm_pud[PTRS_PER_PUD] __bss_pgtbl __maybe_unused;
+static pmd_t bm_pmd[PTRS_PER_PMD] __rodata_pgtbl;
+static pud_t bm_pud[PTRS_PER_PUD] __rodata_pgtbl;
const size_t fixmap_bm_pte_size = sizeof(fixmap_bm_pte);
--
2.55.0.887.g758fc8c411-goog