* [RFC PATCH] arm64: mm: Map fixmap PTE tables r/o in the linear map
@ 2026-08-05 10:40 Ard Biesheuvel
0 siblings, 0 replies; only message in thread
From: Ard Biesheuvel @ 2026-08-05 10:40 UTC (permalink / raw)
To: linux-arm-kernel
Cc: will, catalin.marinas, mark.rutland, Ard Biesheuvel, Ryan Roberts,
Anshuman Khandual, Kevin Brodsky, Liz Prucka, Seth Jenkins,
Kees Cook, Jann Horn, linux-hardening
From: Ard Biesheuvel <ardb@kernel.org>
Without physical KASLR, the fixmap page tables will appear at an a
priori known offset in the physical address space, and due to the lack
of randomization, the linear map carries a writeable alias of the fixmap
PTE pages, which appears at an offset in the kernel VA space that is
also predictable.
Given that the placement of the fixmap area is never randomized either,
a single store to this linear alias region is sufficient to map any
physical page with any permissions at a known offset in the kernel VA
space, including on top of the PTI trampoline.
Avoid this, by remapping the fixmap PTE pages read-only in the linear
map. This is possible because all updates to bm_pte[] occur via the
mapping of the kernel image in the vmap area. A read-only mapping is
still needed for things like ptdump that walk the page tables.
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Kevin Brodsky <kevin.brodsky@arm.com>
Cc: Liz Prucka <lizprucka@google.com>
Cc: Seth Jenkins <sethjenkins@google.com>
Cc: Kees Cook <kees@kernel.org>
Cc: Jann Horn <jannh@google.com>
Cc: linux-hardening@vger.kernel.org
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm64/include/asm/set_memory.h | 2 ++
arch/arm64/mm/fixmap.c | 7 +++++++
arch/arm64/mm/pageattr.c | 10 ++++++++++
3 files changed, 19 insertions(+)
diff --git a/arch/arm64/include/asm/set_memory.h b/arch/arm64/include/asm/set_memory.h
index 90f61b17275e..a685fb534c3e 100644
--- a/arch/arm64/include/asm/set_memory.h
+++ b/arch/arm64/include/asm/set_memory.h
@@ -11,6 +11,8 @@ bool can_set_direct_map(void);
int set_memory_valid(unsigned long addr, int numpages, int enable);
+int set_direct_map_ro(unsigned long addr, int numpages);
+
int set_direct_map_invalid_noflush(struct page *page);
int set_direct_map_default_noflush(struct page *page);
int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid);
diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c
index f66a0016dd02..fcb571dffe82 100644
--- a/arch/arm64/mm/fixmap.c
+++ b/arch/arm64/mm/fixmap.c
@@ -14,6 +14,7 @@
#include <asm/fixmap.h>
#include <asm/kernel-pgtable.h>
#include <asm/pgalloc.h>
+#include <asm/set_memory.h>
#include <asm/tlbflush.h>
/* ensure that the fixmap region does not grow down into the PCI I/O region */
@@ -173,3 +174,9 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
return dt_virt;
}
+
+static int __init fixmap_remap_ro(void)
+{
+ return set_direct_map_ro((unsigned long)lm_alias(&bm_pte), NR_BM_PTE_TABLES);
+}
+late_initcall(fixmap_remap_ro);
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index bbe98ac9ad8c..5072b14d4f9d 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -251,6 +251,16 @@ int set_memory_valid(unsigned long addr, int numpages, int enable)
__pgprot(PTE_PRESENT_VALID_KERNEL));
}
+int set_direct_map_ro(unsigned long addr, int numpages)
+{
+ if (!can_set_direct_map())
+ return 0;
+
+ return __change_memory_common(addr, PAGE_SIZE * numpages,
+ __pgprot(PTE_RDONLY),
+ __pgprot(PTE_WRITE));
+}
+
int set_direct_map_invalid_noflush(struct page *page)
{
pgprot_t clear_mask = __pgprot(PTE_PRESENT_VALID_KERNEL);
--
2.55.0.571.g244d577d93-goog
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-08-05 10:40 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-05 10:40 [RFC PATCH] arm64: mm: Map fixmap PTE tables r/o in the linear map Ard Biesheuvel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox