From patchwork Thu Aug 10 17:26:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Garnier X-Patchwork-Id: 9894319 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2468C60236 for ; Thu, 10 Aug 2017 17:29:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0AA0E1FF61 for ; Thu, 10 Aug 2017 17:29:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F1FDA285F0; Thu, 10 Aug 2017 17:29:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 21F2227C05 for ; Thu, 10 Aug 2017 17:29:10 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dfrEx-0008LV-KX; Thu, 10 Aug 2017 17:27:23 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dfrEv-0008F4-Ai for xen-devel@lists.xenproject.org; Thu, 10 Aug 2017 17:27:21 +0000 Received: from [85.158.143.35] by server-2.bemta-6.messagelabs.com id 85/6F-27137-8779C895; Thu, 10 Aug 2017 17:27:20 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrCIsWRWlGSWpSXmKPExsVyMfTAFt3y6T2 RBieWqlp83zKZyYHR4/CHKywBjFGsmXlJ+RUJrBkbj+sWvHGs2Pn3J3MDY49FFyMXh5DADEaJ 5vMz2UEcFoFXLBLHdm1jBnEkBPpZJba+v83WxcgJ5MRJ/Fz1kxXCrpJ4tfslC4gtJKAksXXDU maIUf8YJU5saANrYBPQktjTMJ8JJCEisFRQ4mTrNUYQh1mghUniyb9tTCBVwgLBEpfOr2cHsV kEVCVmLX7EDGLzClhKLPgykwlinYnEk9ZJjCA2J1B82rKZzBCrLSSm/lrJNIFRYAEjwypGjeL UorLUIl1DI72kosz0jJLcxMwcXUMDM73c1OLixPTUnMSkYr3k/NxNjMDwYgCCHYyXNwYcYpTk YFIS5S3+1B0pxJeUn1KZkVicEV9UmpNafIhRhoNDSYK3YlpPpJBgUWp6akVaZg4w0GHSEhw8S iK8W6cCpXmLCxJzizPTIVKnGO05rlxZ94WJY8qB7UCyY8bPb0wcryb8/8YkxJKXn5cqJc5rDT JVAKQtozQPbigsMi8xykoJ8zICnSnEU5BalJtZgir/ilGcg1FJmPciyHKezLwSuN2vgM5iAjo rwrcT5KySRISUVAPjilsWif2GEeFmjbNad6WcviOiJMG+ZtWt4JMT4pz0pp2uupQ6ebXj7y1H iln/dK7wXBGom6K/oVQhY2qU3L4Zvl5Niy603p64ePPTJzWes/9Elkneyfl05oqI8Nu/tkz+H eZ71nOmd7l/urnT/rSU5muf/OKZh6cvndLc8PHuMq7a1a+nWcWIKbEUZyQaajEXFScCAAa/L4 HHAgAA X-Env-Sender: thgarnie@google.com X-Msg-Ref: server-14.tower-21.messagelabs.com!1502386038!70719405!1 X-Originating-IP: [209.85.192.180] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Received: (qmail 18047 invoked from network); 10 Aug 2017 17:27:19 -0000 Received: from mail-pf0-f180.google.com (HELO mail-pf0-f180.google.com) (209.85.192.180) by server-14.tower-21.messagelabs.com with AES128-GCM-SHA256 encrypted SMTP; 10 Aug 2017 17:27:19 -0000 Received: by mail-pf0-f180.google.com with SMTP id o86so5679869pfj.1 for ; Thu, 10 Aug 2017 10:27:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=c1uZd9gLc6JJluCmWy/FHOlCUSMYDJxmZ38NZiqKxmM=; b=MhpcuLhGJwYaWllOKqPsgAdnLTplPTnVRFK7NiMESm6Zib7fAYZn1oVGOx73Xr8U04 CHY7IIg+mka6WzfgcyvN9Wf748M72PAqYgoR1UcFj0ZK3kuS/Q5cJrbmL0NkdsoQwz7A 6hlt8I7kKiqk3nPgH6TNCMf7+eKzmGsMwuuEiKdZaIRo0//wkGisIEct75fOOTGjIwJg GWd8dsGP2vfqqxQKKLyrZ8NaRmScKYuJ8um8NreCu1uvMlCHEJDdGmhR7qCOa83+rJ93 JF56DElNTJ008gvh7+hVTzWpoKT50WGPT6JUeacNMN2y/BHxP3QTy3P9uYWPiSlBH1HE ymtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=c1uZd9gLc6JJluCmWy/FHOlCUSMYDJxmZ38NZiqKxmM=; b=reKmcXzsf0Ndjv+8Knyil7nOpGi984KmBkxUhrk77t9XilFsO48g3r6aSre72vvVpT iQnjVFijzflbDvyioSKav/dvXKeS06Nfc01rM7bjy5YMdYdPTT/XarwfV8GnUlmn0S74 PFq8r+kRQAIa4BTgOZZDgRD3qlvMyy/VlaT+8K+lJy8ytk4m7QbBpO/JFL6Ze5YN1wJM tMAnVOSPY1sfcLLv5aKpz2ygGlzfoG+386EIN7evqPaH+pgKDQmtTtuf+QS6uuINZNMh jUgJL0evl0qUfT2iBo7kIRKSwXn+HkBXwshLziI9wzXKYQRUc8VPaPvjqsynJOTtjGlI LTjA== X-Gm-Message-State: AHYfb5hVWo6eKv9nLPhFdXk2PU2MlA8B471vu8cI11tqY27rNvz78d20 jIa5Sz7x3bM7mmVV X-Received: by 10.84.217.23 with SMTP id o23mr14273330pli.243.1502386037540; Thu, 10 Aug 2017 10:27:17 -0700 (PDT) Received: from skynet.sea.corp.google.com ([172.31.92.33]) by smtp.gmail.com with ESMTPSA id p77sm11894925pfi.153.2017.08.10.10.27.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 10 Aug 2017 10:27:16 -0700 (PDT) From: Thomas Garnier To: Herbert Xu , "David S . Miller" , Thomas Gleixner , Ingo Molnar , "H . Peter Anvin" , Peter Zijlstra , Josh Poimboeuf , Arnd Bergmann , Thomas Garnier , Matthias Kaehlcke , Boris Ostrovsky , Juergen Gross , Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Joerg Roedel , Tom Lendacky , Andy Lutomirski , Borislav Petkov , Brian Gerst , "Kirill A . Shutemov" , "Rafael J . Wysocki" , Len Brown , Pavel Machek , Tejun Heo , Christoph Lameter , Paul Gortmaker , Chris Metcalf , Andrew Morton , "Paul E . McKenney" , Nicolas Pitre , Christopher Li , "Rafael J . Wysocki" , Lukas Wunner , Mika Westerberg , Dou Liyang , Daniel Borkmann , Alexei Starovoitov , Masahiro Yamada , Markus Trippelsdorf , Steven Rostedt , Kees Cook , Rik van Riel , David Howells , Waiman Long , Kyle Huey , Peter Foley , Tim Chen , Catalin Marinas , Ard Biesheuvel , Michal Hocko , Matthew Wilcox , "H . J . Lu" , Paul Bolle , Rob Landley , Baoquan He , Daniel Micay Date: Thu, 10 Aug 2017 10:26:15 -0700 Message-Id: <20170810172615.51965-24-thgarnie@google.com> X-Mailer: git-send-email 2.14.0.434.g98096fd7a8-goog In-Reply-To: <20170810172615.51965-1-thgarnie@google.com> References: <20170810172615.51965-1-thgarnie@google.com> Cc: linux-arch@vger.kernel.org, kvm@vger.kernel.org, linux-pm@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org, linux-sparse@vger.kernel.org, linux-crypto@vger.kernel.org, kernel-hardening@lists.openwall.com, xen-devel@lists.xenproject.org Subject: [Xen-devel] [RFC v2 23/23] x86/kaslr: Add option to extend KASLR range from 1GB to 3GB X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add a new CONFIG_RANDOMIZE_BASE_LARGE option to benefit from PIE support. It increases the KASLR range from 1GB to 3GB. The new range stars at 0xffffffff00000000 just above the EFI memory region. This option is off by default. The boot code is adapted to create the appropriate page table spanning three PUD pages. The relocation table uses 64-bit integers generated with the updated relocation tool with the large-reloc option. Signed-off-by: Thomas Garnier --- arch/x86/Kconfig | 21 +++++++++++++++++++++ arch/x86/boot/compressed/Makefile | 5 +++++ arch/x86/boot/compressed/misc.c | 10 +++++++++- arch/x86/include/asm/page_64_types.h | 9 +++++++++ arch/x86/kernel/head64.c | 18 ++++++++++++++---- arch/x86/kernel/head_64.S | 11 ++++++++++- 6 files changed, 68 insertions(+), 6 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 2b69be667543..f3027000ec60 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2149,6 +2149,27 @@ config X86_MODULE_PLTS select X86_MODULE_MODEL_LARGE select HAVE_MOD_ARCH_SPECIFIC +config RANDOMIZE_BASE_LARGE + bool "Increase the randomization range of the kernel image" + depends on X86_64 && RANDOMIZE_BASE + select X86_PIE + select X86_MODULE_PLTS if MODULES + default n + ---help--- + Build the kernel as a Position Independent Executable (PIE) and + increase the available randomization range from 1GB to 3GB. + + This option impacts performance on kernel CPU intensive workloads up + to 10% due to PIE generated code. Impact on user-mode processes and + typical usage would be significantly less (0.50% when you build the + kernel). + + The kernel and modules will generate slightly more assembly (1 to 2% + increase on the .text sections). The vmlinux binary will be + significantly smaller due to less relocations. + + If unsure say N + config HOTPLUG_CPU bool "Support for hot-pluggable CPUs" depends on SMP diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 8a958274b54c..94dfee5a7cd2 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -112,7 +112,12 @@ $(obj)/vmlinux.bin: vmlinux FORCE targets += $(patsubst $(obj)/%,%,$(vmlinux-objs-y)) vmlinux.bin.all vmlinux.relocs +# Large randomization require bigger relocation table +ifeq ($(CONFIG_RANDOMIZE_BASE_LARGE),y) +CMD_RELOCS = arch/x86/tools/relocs --large-reloc +else CMD_RELOCS = arch/x86/tools/relocs +endif quiet_cmd_relocs = RELOCS $@ cmd_relocs = $(CMD_RELOCS) $< > $@;$(CMD_RELOCS) --abs-relocs $< $(obj)/vmlinux.relocs: vmlinux FORCE diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index c20cdc7cbd61..82a0ea17c9dc 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -170,10 +170,18 @@ void __puthex(unsigned long value) } #if CONFIG_X86_NEED_RELOCS + +/* Large randomization go lower than -2G and use large relocation table */ +#ifdef CONFIG_RANDOMIZE_BASE_LARGE +typedef long rel_t; +#else +typedef int rel_t; +#endif + static void handle_relocations(void *output, unsigned long output_len, unsigned long virt_addr) { - int *reloc; + rel_t *reloc; unsigned long delta, map, ptr; unsigned long min_addr = (unsigned long)output; unsigned long max_addr = min_addr + (VO___bss_start - VO__text); diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h index 3f5f08b010d0..6b65f846dd64 100644 --- a/arch/x86/include/asm/page_64_types.h +++ b/arch/x86/include/asm/page_64_types.h @@ -48,7 +48,11 @@ #define __PAGE_OFFSET __PAGE_OFFSET_BASE #endif /* CONFIG_RANDOMIZE_MEMORY */ +#ifdef CONFIG_RANDOMIZE_BASE_LARGE +#define __START_KERNEL_map _AC(0xffffffff00000000, UL) +#else #define __START_KERNEL_map _AC(0xffffffff80000000, UL) +#endif /* CONFIG_RANDOMIZE_BASE_LARGE */ /* See Documentation/x86/x86_64/mm.txt for a description of the memory map. */ #ifdef CONFIG_X86_5LEVEL @@ -65,9 +69,14 @@ * 512MiB by default, leaving 1.5GiB for modules once the page tables * are fully set up. If kernel ASLR is configured, it can extend the * kernel page table mapping, reducing the size of the modules area. + * On PIE, we relocate the binary 2G lower so add this extra space. */ #if defined(CONFIG_RANDOMIZE_BASE) +#ifdef CONFIG_RANDOMIZE_BASE_LARGE +#define KERNEL_IMAGE_SIZE (_AC(3, UL) * 1024 * 1024 * 1024) +#else #define KERNEL_IMAGE_SIZE (1024 * 1024 * 1024) +#endif #else #define KERNEL_IMAGE_SIZE (512 * 1024 * 1024) #endif diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index e71f27a20576..7e817e804e89 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -39,6 +39,7 @@ static unsigned int __initdata next_early_pgt; pmdval_t early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX); #define __head __section(.head.text) +#define pud_count(x) (((x + (PUD_SIZE - 1)) & ~(PUD_SIZE - 1)) >> PUD_SHIFT) static void __head *fixup_pointer(void *ptr, unsigned long physaddr) { @@ -56,6 +57,8 @@ unsigned long __head notrace __startup_64(unsigned long physaddr, { unsigned long load_delta, *p; unsigned long pgtable_flags; + unsigned long level3_kernel_start, level3_kernel_count; + unsigned long level3_fixmap_start; pgdval_t *pgd; p4dval_t *p4d; pudval_t *pud; @@ -82,6 +85,11 @@ unsigned long __head notrace __startup_64(unsigned long physaddr, /* Include the SME encryption mask in the fixup value */ load_delta += sme_get_me_mask(); + /* Look at the randomization spread to adapt page table used */ + level3_kernel_start = pud_index(__START_KERNEL_map); + level3_kernel_count = pud_count(KERNEL_IMAGE_SIZE); + level3_fixmap_start = level3_kernel_start + level3_kernel_count; + /* Fixup the physical addresses in the page table */ pgd = fixup_pointer(&early_top_pgt, physaddr); @@ -93,8 +101,9 @@ unsigned long __head notrace __startup_64(unsigned long physaddr, } pud = fixup_pointer(&level3_kernel_pgt, physaddr); - pud[510] += load_delta; - pud[511] += load_delta; + for (i = 0; i < level3_kernel_count; i++) + pud[level3_kernel_start + i] += load_delta; + pud[level3_fixmap_start] += load_delta; pmd = fixup_pointer(level2_fixmap_pgt, physaddr); pmd[506] += load_delta; @@ -147,7 +156,7 @@ unsigned long __head notrace __startup_64(unsigned long physaddr, */ pmd = fixup_pointer(level2_kernel_pgt, physaddr); - for (i = 0; i < PTRS_PER_PMD; i++) { + for (i = 0; i < PTRS_PER_PMD * level3_kernel_count; i++) { if (pmd[i] & _PAGE_PRESENT) pmd[i] += load_delta; } @@ -322,7 +331,8 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) */ BUILD_BUG_ON(MODULES_VADDR < __START_KERNEL_map); BUILD_BUG_ON(MODULES_VADDR - __START_KERNEL_map < KERNEL_IMAGE_SIZE); - BUILD_BUG_ON(MODULES_LEN + KERNEL_IMAGE_SIZE > 2*PUD_SIZE); + BUILD_BUG_ON(!IS_ENABLED(CONFIG_RANDOMIZE_BASE_LARGE) && + MODULES_LEN + KERNEL_IMAGE_SIZE > 2*PUD_SIZE); BUILD_BUG_ON((__START_KERNEL_map & ~PMD_MASK) != 0); BUILD_BUG_ON((MODULES_VADDR & ~PMD_MASK) != 0); BUILD_BUG_ON(!(MODULES_VADDR > __START_KERNEL)); diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 68bf7892f201..d53942ee83eb 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -39,11 +39,15 @@ #define p4d_index(x) (((x) >> P4D_SHIFT) & (PTRS_PER_P4D-1)) #define pud_index(x) (((x) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) +#define pud_count(x) (((x + (PUD_SIZE - 1)) & ~(PUD_SIZE - 1)) >> PUD_SHIFT) PGD_PAGE_OFFSET = pgd_index(__PAGE_OFFSET_BASE) PGD_START_KERNEL = pgd_index(__START_KERNEL_map) L3_START_KERNEL = pud_index(__START_KERNEL_map) +/* Adapt page table L3 space based on range of randomization */ +L3_KERNEL_ENTRY_COUNT = pud_count(KERNEL_IMAGE_SIZE) + .text __HEAD .code64 @@ -411,7 +415,12 @@ NEXT_PAGE(level4_kernel_pgt) NEXT_PAGE(level3_kernel_pgt) .fill L3_START_KERNEL,8,0 /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */ - .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC + i = 0 + .rept L3_KERNEL_ENTRY_COUNT + .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC \ + + PAGE_SIZE*i + i = i + 1 + .endr .quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC NEXT_PAGE(level2_kernel_pgt)