Now new randomized output can only be chosen from regions above loaded address. In this case, for bootloaders like kexec which always loads kernel near the end of ram, it doesn't do randomization at all. Or kernel is loaded in a very big starting address, we should not give up that area is loaded in a very large address, then the area below the large loaded address will be given up. This is not reasonable.
With correct tracking in mem_avoid we can allow random output below loaded address. With this change, though kexec can get random ouput below its loaded address of kernel. Now we just pick 512M as min_addr. If kernel loaded address is bigger than 512M, E.g 8G. Then [512M, 8G) can be added into random output candidate area. Signed-off-by: Yinghai Lu <ying...@kernel.org> --- v4->v5: Kees suggested changing the code comment related to minimum address to make it more understandable. arch/x86/boot/compressed/aslr.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/x86/boot/compressed/aslr.c b/arch/x86/boot/compressed/aslr.c index ddfc3d0..bbd2d06 100644 --- a/arch/x86/boot/compressed/aslr.c +++ b/arch/x86/boot/compressed/aslr.c @@ -446,7 +446,8 @@ void choose_kernel_location(unsigned char *input, unsigned long output_size, unsigned char **virt_offset) { - unsigned long random; + unsigned long random, min_addr; + *virt_offset = (unsigned char *)LOAD_PHYSICAL_ADDR; #ifdef CONFIG_HIBERNATION @@ -467,8 +468,13 @@ void choose_kernel_location(unsigned char *input, mem_avoid_init((unsigned long)input, input_size, (unsigned long)*output); + /* Lower minimum to 512M. */ + min_addr = (unsigned long)*output; + if (min_addr > (512UL<<20)) + min_addr = 512UL<<20; + /* Walk e820 and find a random address. */ - random = find_random_phy_addr((unsigned long)*output, output_size); + random = find_random_phy_addr(min_addr, output_size); if (!random) debug_putstr("KASLR could not find suitable E820 region...\n"); else { -- 2.5.0