Skip to content

Commit f2ba877

Browse files
ardbiesheuvelwilldeacon
authored andcommitted
arm64: mm: Map the kernel data/bss read-only in the linear map
On systems where the bootloader adheres to the original arm64 boot protocol, the placement of the kernel in the physical address space is highly predictable, and this makes the placement of its linear alias in the kernel virtual address space equally predictable, given the lack of randomization of the linear map. The linear aliases of the kernel text and rodata regions are already mapped read-only, but the kernel data and bss are mapped read-write in this region. This is not needed, so map them read-only as well. Note that the statically allocated kernel page tables do need to be modifiable via the linear map, so leave these mapped read-write. Reviewed-by: Kevin Brodsky <kevin.brodsky@arm.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
1 parent 0aae825 commit f2ba877

1 file changed

Lines changed: 13 additions & 2 deletions

File tree

arch/arm64/mm/mmu.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,7 +1138,9 @@ static void __init map_mem(void)
11381138
{
11391139
static const u64 direct_map_end = _PAGE_END(VA_BITS_MIN);
11401140
phys_addr_t kernel_start = __pa_symbol(_text);
1141-
phys_addr_t kernel_end = __pa_symbol(__init_begin);
1141+
phys_addr_t init_begin = __pa_symbol(__init_begin);
1142+
phys_addr_t init_end = __pa_symbol(__init_end);
1143+
phys_addr_t kernel_end = __pa_symbol(__bss_stop);
11421144
phys_addr_t start, end;
11431145
int flags = NO_EXEC_MAPPINGS;
11441146
u64 i;
@@ -1173,7 +1175,11 @@ static void __init map_mem(void)
11731175
* contents of the region accessible to subsystems such as hibernate,
11741176
* but protects it from inadvertent modification or execution.
11751177
*/
1176-
__map_memblock(kernel_start, kernel_end, pgprot_tagged(PAGE_KERNEL),
1178+
__map_memblock(kernel_start, init_begin, pgprot_tagged(PAGE_KERNEL),
1179+
flags);
1180+
1181+
/* Map the kernel data/bss so it can be remapped later */
1182+
__map_memblock(init_end, kernel_end, pgprot_tagged(PAGE_KERNEL),
11771183
flags);
11781184

11791185
/* map all the memory banks */
@@ -1186,6 +1192,11 @@ static void __init map_mem(void)
11861192
__map_memblock(start, end, pgprot_tagged(PAGE_KERNEL),
11871193
flags);
11881194
}
1195+
1196+
/* Map the kernel data/bss read-only in the linear map */
1197+
__map_memblock(init_end, kernel_end, PAGE_KERNEL_RO, flags);
1198+
flush_tlb_kernel_range((unsigned long)lm_alias(__init_end),
1199+
(unsigned long)lm_alias(__bss_stop));
11891200
}
11901201

11911202
void mark_rodata_ro(void)

0 commit comments

Comments
 (0)