Skip to content

Commit 98e23ea

Browse files
Ard BiesheuvelAlex Shi
authored andcommitted
arm64: kaslr: randomize the linear region
When KASLR is enabled (CONFIG_RANDOMIZE_BASE=y), and entropy has been provided by the bootloader, randomize the placement of RAM inside the linear region if sufficient space is available. For instance, on a 4KB granule/3 levels kernel, the linear region is 256 GB in size, and we can choose any 1 GB aligned offset that is far enough from the top of the address space to fit the distance between the start of the lowest memblock and the top of the highest memblock. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> (cherry picked from commit c031a4213c11a5db475f528c182f7b3858df11db) Signed-off-by: Alex Shi <alex.shi@linaro.org>
1 parent d0a12e9 commit 98e23ea

2 files changed

Lines changed: 24 additions & 2 deletions

File tree

arch/arm64/kernel/kaslr.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <asm/sections.h>
2222

2323
u64 __read_mostly module_alloc_base;
24+
u16 __initdata memstart_offset_seed;
2425

2526
static __init u64 get_kaslr_seed(void *fdt)
2627
{
@@ -123,6 +124,9 @@ u64 __init kaslr_early_init(u64 dt_phys)
123124
mask = ((1UL << (VA_BITS - 2)) - 1) & ~(SZ_2M - 1);
124125
offset = seed & mask;
125126

127+
/* use the top 16 bits to randomize the linear region */
128+
memstart_offset_seed = seed >> 48;
129+
126130
/*
127131
* The kernel Image should not extend across a 1GB/32MB/512MB alignment
128132
* boundary (for 4KB/16KB/64KB granule kernels, respectively). If this

arch/arm64/mm/init.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,23 @@ void __init arm64_memblock_init(void)
196196
memblock_add(__pa(_text), (u64)(_end - _text));
197197
}
198198

199+
if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
200+
extern u16 memstart_offset_seed;
201+
u64 range = linear_region_size -
202+
(memblock_end_of_DRAM() - memblock_start_of_DRAM());
203+
204+
/*
205+
* If the size of the linear region exceeds, by a sufficient
206+
* margin, the size of the region that the available physical
207+
* memory spans, randomize the linear region as well.
208+
*/
209+
if (memstart_offset_seed > 0 && range >= ARM64_MEMSTART_ALIGN) {
210+
range = range / ARM64_MEMSTART_ALIGN + 1;
211+
memstart_addr -= ARM64_MEMSTART_ALIGN *
212+
((range * memstart_offset_seed) >> 16);
213+
}
214+
}
215+
199216
/*
200217
* Register the kernel text, kernel data, initrd, and initial
201218
* pagetables with memblock.
@@ -365,12 +382,13 @@ void __init mem_init(void)
365382
#ifdef CONFIG_SPARSEMEM_VMEMMAP
366383
MLG(VMEMMAP_START,
367384
VMEMMAP_START + VMEMMAP_SIZE),
368-
MLM((unsigned long)virt_to_page(PAGE_OFFSET),
385+
MLM((unsigned long)phys_to_page(memblock_start_of_DRAM()),
369386
(unsigned long)virt_to_page(high_memory)),
370387
#endif
371388
MLK(FIXADDR_START, FIXADDR_TOP),
372389
MLM(PCI_IO_START, PCI_IO_END),
373-
MLM(PAGE_OFFSET, (unsigned long)high_memory));
390+
MLM(__phys_to_virt(memblock_start_of_DRAM()),
391+
(unsigned long)high_memory));
374392

375393
#undef MLK
376394
#undef MLM

0 commit comments

Comments
 (0)