Skip to content

Commit

Permalink
arm64: kaslr: randomize the linear region
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ard Biesheuvel authored and Catalin Marinas committed Feb 24, 2016
1 parent f80fb3a commit c031a42
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
4 changes: 4 additions & 0 deletions arch/arm64/kernel/kaslr.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <asm/sections.h>

u64 __read_mostly module_alloc_base;
u16 __initdata memstart_offset_seed;

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

/* use the top 16 bits to randomize the linear region */
memstart_offset_seed = seed >> 48;

/*
* The kernel Image should not extend across a 1GB/32MB/512MB alignment
* boundary (for 4KB/16KB/64KB granule kernels, respectively). If this
Expand Down
22 changes: 20 additions & 2 deletions arch/arm64/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,23 @@ void __init arm64_memblock_init(void)
memblock_add(__pa(_text), (u64)(_end - _text));
}

if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
extern u16 memstart_offset_seed;
u64 range = linear_region_size -
(memblock_end_of_DRAM() - memblock_start_of_DRAM());

/*
* If the size of the linear region exceeds, by a sufficient
* margin, the size of the region that the available physical
* memory spans, randomize the linear region as well.
*/
if (memstart_offset_seed > 0 && range >= ARM64_MEMSTART_ALIGN) {
range = range / ARM64_MEMSTART_ALIGN + 1;
memstart_addr -= ARM64_MEMSTART_ALIGN *
((range * memstart_offset_seed) >> 16);
}
}

/*
* Register the kernel text, kernel data, initrd, and initial
* pagetables with memblock.
Expand Down Expand Up @@ -365,12 +382,13 @@ void __init mem_init(void)
#ifdef CONFIG_SPARSEMEM_VMEMMAP
MLG((unsigned long)vmemmap,
(unsigned long)vmemmap + VMEMMAP_SIZE),
MLM((unsigned long)virt_to_page(PAGE_OFFSET),
MLM((unsigned long)phys_to_page(memblock_start_of_DRAM()),
(unsigned long)virt_to_page(high_memory)),
#endif
MLK(FIXADDR_START, FIXADDR_TOP),
MLM(PCI_IO_START, PCI_IO_END),
MLM(PAGE_OFFSET, (unsigned long)high_memory));
MLM(__phys_to_virt(memblock_start_of_DRAM()),
(unsigned long)high_memory));

#undef MLK
#undef MLM
Expand Down

0 comments on commit c031a42

Please sign in to comment.