[Patch v3 0/7] randomize kernel physical address and virtual address separately

From: Baoquan He
Date: Sun Mar 08 2015 - 01:18:49 EST


Currently kaslr only randomize physical address of kernel loading, then add
the delta to virtual address of kernel text mapping. Because kernel virtual
address can only be from __START_KERNEL_map to

LOAD_PHYSICAL_ADDR+CONFIG_RANDOMIZE_BASE_MAX_OFFSET,

namely [0xffffffff80000000, 0xffffffffc0000000], so physical address can only
be randomized in region [LOAD_PHYSICAL_ADDR, CONFIG_RANDOMIZE_BASE_MAX_OFFSET],
namely [16M, 1G].

So hpa and Vivek suggested the randomization should be done separately for both
physical and virtual address. In this patchset the behavior is changed. Randomize
both the physical address where kernel is decompressed and the virtual address
where kernel text is mapped. And physical address can be randomized from where
vmlinux was linked to load to maximum physical memory, possibly near 64T. While
virtual address can get a random offset from load address to
CONFIG_RANDOMIZE_BASE_MAX_OFFSET, then added to __START_KERNEL_map. And relocation
handling only depends on virtual address randomization. Means if and only if
virtual address is randomized to a different value, add the delta to the offset
of kernel relocs.

This patchset depends on Yinghai's patch set which makes kaslr clean up
and build ident mapping to make kernel be able to be reloaded above 4G.
People can get his related patchset in below link, then apply this patchset
on top of it for testing and reviewing.

https://git.kernel.org/cgit/linux/kernel/git/yinghai/linux-yinghai.git/log/?h=for-x86-4.0-rc2-aslr
or
git://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-yinghai.git for-x86-4.0-rc2-aslr

Issue need be discussed:

Currently kaslr only randomize from the original address where bootloader
put kernel. However some bootloaders may put kernel in a very high address.
Then possibly a very huge region below that address won't be calculated
and added as candidate slots. Yinghai uses a patched grub2 to do this
right now, put kernel near 5G. And he suggested moving down random base
to 512M when it's bigger than this value. But 512M seems a little arbitrary
because I can't see its theoretical foundation. I am wondering how about
16M since Yinghai said currently all related data in boot stage has been
avoided safely. Any opinion?

v1->v2:
Thanks to Yinghai's patch which make kernel be able to load above 4G in boot stage,
physical address can be randomized anywhere, even near 64T.

v2>v3:
Rearrange patchset to make it bisect-able according to Yinghai's comment.

Fix two code bugs in process_e820_entry and slots_fetch_random.

Baoquan He (7):
x86, kaslr: Fix a bug that relocation can not be handled when kernel
is loaded above 2G
x86, kaslr: Introduce struct slot_area to manage randomization slot
info
x86, kaslr: Add two functions which will be used later
x86, kaslr: Introduce fetch_random_virt_offset to randomize the kernel
text mapping address
x86, kaslr: Randomize physical and virtual address of kernel
separately
x86, kaslr: Add support of kernel physical address randomization above
4G
x86, kaslr: Remove useless codes

arch/x86/boot/compressed/aslr.c | 215 +++++++++++++++++++++++++++++-----------
arch/x86/boot/compressed/misc.c | 41 +++++---
arch/x86/boot/compressed/misc.h | 24 +++--
3 files changed, 194 insertions(+), 86 deletions(-)

--
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/