From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932714AbcCVHf2 (ORCPT ); Tue, 22 Mar 2016 03:35:28 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41471 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758273AbcCVHeA (ORCPT ); Tue, 22 Mar 2016 03:34:00 -0400 From: Baoquan He To: linux-kernel@vger.kernel.org Cc: yinghai@kernel.org, keescook@chromium.org, hpa@zytor.com, mingo@redhat.com, bp@alien8.de, vgoyal@redhat.com, luto@kernel.org, lasse.collin@tukaani.org, akpm@linux-foundation.org, dyoung@redhat.com Subject: [PATCH v4 19/20] x86, kaslr: Allow random address to be below loaded address Date: Tue, 22 Mar 2016 15:32:16 +0800 Message-Id: <1458631937-14593-20-git-send-email-bhe@redhat.com> In-Reply-To: <1458631937-14593-1-git-send-email-bhe@redhat.com> References: <1458631937-14593-1-git-send-email-bhe@redhat.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Yinghai Lu 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 --- 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..d072ca7 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); + /* start from 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