Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2178239imu; Thu, 29 Nov 2018 00:18:06 -0800 (PST) X-Google-Smtp-Source: AFSGD/U4qXvghYaL/r9+kEvVqxHxHsqFHM/kXhfSH+mAviO6Eo59bHszoBNdtzXuQ32jkiKaBkMN X-Received: by 2002:a63:801:: with SMTP id 1mr409252pgi.275.1543479486771; Thu, 29 Nov 2018 00:18:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543479486; cv=none; d=google.com; s=arc-20160816; b=AeYeMMvTSp+2FdZtgXwMoE59W1mray8D+zoIm2NhqCv5xfJh4ry98EpZH3yuj9cCpp Un+BqMLTchnaDfjsJuoe9zJ2UtEAagUjgQ1e34GLAFPptTDEGL3OkyOum1VXEFin7RQe R45OzGqcNW21h1vnaHMEDpDA0gnEZo3JiFQuREOKZJ+lcNf325L9KUnIBOtvShsODwqr 89eblXDCYdx79bjv+H/0Oih19+lzDEPHfRGDr3dhXzRgbraA5W1msXxhuznhFTjP9i4u TgrEm2XE1x3ZESOVqIibpKLEsOPoMw09TSQEMj6IN+E/umU0NMp7w1i6pdoF1QlCU5kQ O+qg== 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=2frQDxcthzcLRFcufEfXfY/K2Av8grvmv4iQy6KHnrk=; b=GIktKTpwFGDCVltgZ2EYScoLqn5hzqQOk7ZjeUufsZenylUD4Th/xv1to/NEV6BkQ4 BistoeNJmF+TzU0f3RVCAYkC9KTtEj5B/GBxab+YsY1HSnZQt/JZcY/9M7fmLVLEZ6wv rP5e4ZH+IeCU7Kg8eW4tk93Qx1kNew7GN6p3nQ8mtczaq+Vv0c+5FW9wOwK3fbEkRl16 Z5hdqEJrJ1+cCvwjzSx9rMzyoQ6/GPF0ADRRphoSnnf0TDcUKGn7Cbpv/DjW6jQh3kvj jyfEsuDTIZY1FKIqsP/LPT9iLAuSaYQseeq3G0NKzqirxKr6OCkKzYcv/Vg+tvf41w0w YwiA== 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 a34-v6si1493073pld.249.2018.11.29.00.17.52; Thu, 29 Nov 2018 00:18:06 -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 S1727981AbeK2TVf (ORCPT + 99 others); Thu, 29 Nov 2018 14:21:35 -0500 Received: from mail.cn.fujitsu.com ([183.91.158.132]:27144 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727490AbeK2TVf (ORCPT ); Thu, 29 Nov 2018 14:21:35 -0500 X-IronPort-AV: E=Sophos;i="5.56,293,1539619200"; d="scan'208";a="48821863" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 29 Nov 2018 16:17:02 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (unknown [10.167.33.80]) by cn.fujitsu.com (Postfix) with ESMTP id C2E6C4B7349C; Thu, 29 Nov 2018 16:17:00 +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; Thu, 29 Nov 2018 16:17:06 +0800 From: Chao Fan To: , , , , , , , , CC: , , Subject: [PATCH v12 5/5] x86/boot/KASLR: Limit KASLR to extracting kernel in immovable memory Date: Thu, 29 Nov 2018 16:16:31 +0800 Message-ID: <20181129081631.11139-6-fanc.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181129081631.11139-1-fanc.fnst@cn.fujitsu.com> References: <20181129081631.11139-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: C2E6C4B7349C.AA972 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. This will break memory hotplug feature and make the movable memory chosen by KASLR practically immovable. The solution is to limit KASLR to choose memory regions in immovable node according to SRAT tables. If CONFIG_EARLY_PARSE_RSDP is enabled, walk through the SRAT memory tables and store those immovable memory regions so that KASLR can get where to choose for randomization. Also, 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 | 75 +++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 11 deletions(-) diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index b251572e77af..f0c30e3ddcb4 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -97,6 +97,11 @@ 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_MEMORY_HOTREMOVE +/* Store the immovable memory regions */ +extern struct mem_vector immovable_mem[MAX_NUMNODES*2]; +#endif + enum mem_avoid_index { MEM_AVOID_ZO_RANGE = 0, @@ -413,6 +418,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 +576,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 +654,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_PARSE_RSDP + /* + * 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++) { + struct mem_vector entry; + unsigned long long start, end, entry_end, region_end; + + 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 +770,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 +798,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.19.1