Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3117463imu; Sun, 6 Jan 2019 19:25:14 -0800 (PST) X-Google-Smtp-Source: ALg8bN41SUtDPYONQqtc3fpT6q8jdEPjlTE3O4wKYpeOUxWQkaIv0nedZE7bY2agS7+ITZC6xdX1 X-Received: by 2002:a63:2c82:: with SMTP id s124mr9350307pgs.73.1546831514936; Sun, 06 Jan 2019 19:25:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1546831514; cv=none; d=google.com; s=arc-20160816; b=b/G3fh/SX73L354cVArXUNNfumvv9iP80wYk9Qrq4m57kZdxirzJqCchVJQYgPp3Ck YGjM3Rfd9Z589xP+ds9z7op2R10jcc3Gag2rLq5jiKcAF6xqDjdZ3oFuFsSjQVaSXynP DAk5QRGSm8CanLfA1xrwSfX/04OKZGp58UCpfgWGPW3jdMBmZ92NkD3+4A4wEdsmyRkq ggrbCBRW8U0QMGBf+eXsnfY5JMk3mGbZnNx3f70+tjZSRtHG2fqWQ3nOgnuCieUpe+K8 eBoFdr4VQXzrHN0USiqiDMopoTjrdf0nNwCsHr/1YRHQhibSyaPQQOKVW5g+lTF2ry5r DJdw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=3SmOVIntCMqMBBsBGBGiCBPOwEZCCB0cWnz41jKf0b8=; b=Sf1XBgpxazLHNnEje5hSZWxN4GlJ1fmE1HaW6ARKb2ADs8kxOGAxxSr5mUN9wWgc6s SdSufRWq31e3XmrnX/eLU8Ii0F9LxYMN7mHiWpRXNWmXHngKOiN5cOX1DZSu9d2z+MtZ T1YD/l7avtnGSx/b0Axk0nvKiAqgEjH2sB5RR1B4ighuqjfQPCelDKODdZ5dwWx0y3IM RiSjXh7zrNQI3caOXX9N13mpL4RAoxeiXujoQjoYQDOv8AebyRPQBRSon6kpsRCcmlXX y6/Nz8eYI1bvcC61Xg/rwn/NQ4Gh0cGLIyjO8pXa7+Ypt6UvozvEZATPx7aza8CantIR w3IA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p1si15849372pgb.192.2019.01.06.19.25.00; Sun, 06 Jan 2019 19:25:14 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726418AbfAGDXs (ORCPT + 99 others); Sun, 6 Jan 2019 22:23:48 -0500 Received: from mail.cn.fujitsu.com ([183.91.158.132]:54897 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726180AbfAGDXr (ORCPT ); Sun, 6 Jan 2019 22:23:47 -0500 X-IronPort-AV: E=Sophos;i="5.56,449,1539619200"; d="scan'208";a="51438961" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 07 Jan 2019 11:23:45 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id 10CBB4B7EC62; Mon, 7 Jan 2019 11:23:44 +0800 (CST) Received: from localhost.local (10.167.225.56) by G08CNEXCHPEKD01.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 7 Jan 2019 11:23:48 +0800 From: Chao Fan To: , , , , , , , , CC: , , Subject: [PATCH v15 6/6] x86/boot/KASLR: Limit KASLR to extracting kernel in immovable memory Date: Mon, 7 Jan 2019 11:22:43 +0800 Message-ID: <20190107032243.25324-7-fanc.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190107032243.25324-1-fanc.fnst@cn.fujitsu.com> References: <20190107032243.25324-1-fanc.fnst@cn.fujitsu.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [10.167.225.56] X-yoursite-MailScanner-ID: 10CBB4B7EC62.AD4CF X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: fanc.fnst@cn.fujitsu.com X-Spam-Status: No Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org KASLR may randomly choose some positions which are located in movable memory regions. It will break memory hotplug feature and make the movable memory chosen by KASLR can't be removed. The solution is to limit KASLR to choose memory regions in immovable node according to SRAT tables. When CONFIG_EARLY_SRAT_PARSE is enabled, walk through SRAT to get the information of immovable memory so that KASLR knows where should be chosen for randomization. Rename process_mem_region() as __process_mem_region() and name new function as process_mem_region(). Signed-off-by: Chao Fan --- arch/x86/boot/compressed/kaslr.c | 79 +++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 11 deletions(-) diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index b251572e77af..7dbec6910203 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -97,6 +97,15 @@ static bool memmap_too_large; /* Store memory limit specified by "mem=nn[KMG]" or "memmap=nn[KMG]" */ static unsigned long long mem_limit = ULLONG_MAX; +#ifdef CONFIG_EARLY_SRAT_PARSE +/* + * Information of immovable memory regions. + * Max amount of memory regions is MAX_NUMNODES*2, so need such array + * to place immovable memory regions if all of the memory is immovable. + */ +extern struct mem_vector immovable_mem[MAX_NUMNODES*2]; +#endif + enum mem_avoid_index { MEM_AVOID_ZO_RANGE = 0, @@ -413,6 +422,9 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size, /* Mark the memmap regions we need to avoid */ handle_mem_options(); + /* Mark the immovable regions we need to choose */ + get_immovable_mem(); + #ifdef CONFIG_X86_VERBOSE_BOOTUP /* Make sure video RAM can be used. */ add_identity_map(0, PMD_SIZE); @@ -568,9 +580,9 @@ static unsigned long slots_fetch_random(void) return 0; } -static void process_mem_region(struct mem_vector *entry, - unsigned long minimum, - unsigned long image_size) +static void __process_mem_region(struct mem_vector *entry, + unsigned long minimum, + unsigned long image_size) { struct mem_vector region, overlap; unsigned long start_orig, end; @@ -646,6 +658,57 @@ static void process_mem_region(struct mem_vector *entry, } } +static bool process_mem_region(struct mem_vector *region, + unsigned long long minimum, + unsigned long long image_size) +{ + int i; + /* + * If no immovable memory found, or MEMORY_HOTREMOVE disabled, + * walk all the regions, so use region directly. + */ + if (!num_immovable_mem) { + __process_mem_region(region, minimum, image_size); + + if (slot_area_index == MAX_SLOT_AREA) { + debug_putstr("Aborted e820/efi memmap scan (slot_areas full)!\n"); + return 1; + } + return 0; + } + +#ifdef CONFIG_EARLY_SRAT_PARSE + /* + * If immovable memory found, filter the intersection between + * immovable memory and region to __process_mem_region(). + * Otherwise, go on old code. + */ + for (i = 0; i < num_immovable_mem; i++) { + unsigned long long start, end, entry_end, region_end; + struct mem_vector entry; + + if (!mem_overlaps(region, &immovable_mem[i])) + continue; + + start = immovable_mem[i].start; + end = start + immovable_mem[i].size; + region_end = region->start + region->size; + + entry.start = clamp(region->start, start, end); + entry_end = clamp(region_end, start, end); + entry.size = entry_end - entry.start; + + __process_mem_region(&entry, minimum, image_size); + + if (slot_area_index == MAX_SLOT_AREA) { + debug_putstr("Aborted e820/efi memmap scan (slot_areas full)!\n"); + return 1; + } + } + return 0; +#endif +} + #ifdef CONFIG_EFI /* * Returns true if mirror region found (and must have been processed @@ -711,11 +774,8 @@ process_efi_entries(unsigned long minimum, unsigned long image_size) region.start = md->phys_addr; region.size = md->num_pages << EFI_PAGE_SHIFT; - process_mem_region(®ion, minimum, image_size); - if (slot_area_index == MAX_SLOT_AREA) { - debug_putstr("Aborted EFI scan (slot_areas full)!\n"); + if (process_mem_region(®ion, minimum, image_size)) break; - } } return true; } @@ -742,11 +802,8 @@ static void process_e820_entries(unsigned long minimum, continue; region.start = entry->addr; region.size = entry->size; - process_mem_region(®ion, minimum, image_size); - if (slot_area_index == MAX_SLOT_AREA) { - debug_putstr("Aborted e820 scan (slot_areas full)!\n"); + if (process_mem_region(®ion, minimum, image_size)) break; - } } } -- 2.20.1