From patchwork Wed Jun 20 22:09:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Edgecombe, Rick P" X-Patchwork-Id: 10478777 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 87B41600F6 for ; Wed, 20 Jun 2018 22:09:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 78F7F2883A for ; Wed, 20 Jun 2018 22:09:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6D8BD288BB; Wed, 20 Jun 2018 22:09:39 +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=-2.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E035E2883A for ; Wed, 20 Jun 2018 22:09:38 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 7E2236B0007; Wed, 20 Jun 2018 18:09:34 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 76BFD6B0008; Wed, 20 Jun 2018 18:09:34 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 5E2346B000A; Wed, 20 Jun 2018 18:09:34 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pl0-f70.google.com (mail-pl0-f70.google.com [209.85.160.70]) by kanga.kvack.org (Postfix) with ESMTP id 1DDFD6B0007 for ; Wed, 20 Jun 2018 18:09:34 -0400 (EDT) Received: by mail-pl0-f70.google.com with SMTP id 31-v6so516500plf.19 for ; Wed, 20 Jun 2018 15:09:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references; bh=WTkB5tcz3DMpy0+nWN7Ne43CYx4GTjkaRdEgGc66sdU=; b=eBPDwZE+Yx4sZwhvBj55g32rBMB1JkVbtdd3gMbfNHuEIMO4UBjEUGNjs9GZu/2FkH Z69P1tSSeDP4kIEkWM9V9fEx7cVYvkr/8Euy3P3zKYgpT/ngDkHMYcf0/CCp6Ilg7Xow S6jmiC/m0cH22LyVPw3bXfsyk/IK3Sb5Zz8bftY3cgFUIvP/WAbtRc9YsHWQ0gOa0Lao EuUylYkMxBUH4IAxyfd3g0PvhDLrmxj1utXJLYeMSPFYGRGHG4Q5y6HdA2ouvg8YDfmj cdyUrN6reGE0Kc4P6KgdNWZS+OOU9vJ/6UeDPymqBxT65mIOtGY9ieK/dBcHsM1HB38+ yj+g== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of rick.p.edgecombe@intel.com designates 192.55.52.88 as permitted sender) smtp.mailfrom=rick.p.edgecombe@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Gm-Message-State: APt69E0GYV6tMOukL3qXwEi98V7A4byvGUfNyfqTSip5GO1O0S4wug0E GAspjNp+/Z8OTecfhqv+AzjBstvioqaJtUVmG+l+igcw0zOraOleoFOgTAU+Hh/Ix34Bt9m2TAm XHNerOORX8vo8/FH8BJEK3Du966JU8OLZY6Rp9EiN99NGbtXq7jAwb6XnEVRrcNVq+Q== X-Received: by 2002:a17:902:9b82:: with SMTP id y2-v6mr25908108plp.69.1529532573813; Wed, 20 Jun 2018 15:09:33 -0700 (PDT) X-Google-Smtp-Source: ADUXVKJMKJOPTTOHwddSABaWe2SpF8jgW4Y1AHaNYH42uarEogYEd8/Uy9LI49cic1J1AVnwUOYn X-Received: by 2002:a17:902:9b82:: with SMTP id y2-v6mr25908079plp.69.1529532573059; Wed, 20 Jun 2018 15:09:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529532573; cv=none; d=google.com; s=arc-20160816; b=wJvbteDnfbJrj8hbkFDWC+85yQzuGzSQNN8ECYQZlP72Y2xqZB95DmaEzpuzAla5y7 95Oh65tACOY44RR7TDikmmn7OI3T3L32glcT8L+aVn8ygMHZX+JYeQa7TKfmYHlo0MTW 70cYDK2wQsVsSzd4SyDVyfen3EzMWns80ATFGh6yrWqJlmTCzZqviu8lhs+SeRBvx4QC bKgRuXd2/mrZuPQgj1YLFdTew41o9cRJ412IPw/g7AUq+eJBXRfOSsY19YVsd/NM4yAS MXw/KEdfixmM1clLS3j3MTVyYsTHVduKLhs3UXQs1ZSJqhWLlp+hId5R5HP9zp6ND8Z2 uvAw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=WTkB5tcz3DMpy0+nWN7Ne43CYx4GTjkaRdEgGc66sdU=; b=NzUWFioluiqZ+lL98FYXyKy/fMeKSKmi56ojIyTTtTpB0MpAvmvrHBMu9vmxmeq6lb YmZNJbwFF6Y4rs6+K7zigtTZlzZRD+VQdLCe3TH2TB1Rn4lgcsrtdeJmqgrYnjIGRCLr BbuDYB7Nlmpt2/a8xihmFOGP+N8X3dgJNdK6VWRNxcYDk3NRCXI4Km39/0hYL/wsLdIv YTd9tBhMZrRkxsHW3bFQ1l9QbWl5z7/hS35i00kazBcWsnBFEJS6puKQWW4P9QKMXLs/ /vR9ii9yW5lqTYDUO438vzPmIzCOelk614lJsbhMTqrYkldSdD1+ybIFe1fKMGSU0YD3 rAnw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of rick.p.edgecombe@intel.com designates 192.55.52.88 as permitted sender) smtp.mailfrom=rick.p.edgecombe@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga01.intel.com (mga01.intel.com. [192.55.52.88]) by mx.google.com with ESMTPS id r10-v6si3395620pfe.121.2018.06.20.15.09.32 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 20 Jun 2018 15:09:33 -0700 (PDT) Received-SPF: pass (google.com: domain of rick.p.edgecombe@intel.com designates 192.55.52.88 as permitted sender) client-ip=192.55.52.88; Authentication-Results: mx.google.com; spf=pass (google.com: domain of rick.p.edgecombe@intel.com designates 192.55.52.88 as permitted sender) smtp.mailfrom=rick.p.edgecombe@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Jun 2018 15:09:32 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,249,1526367600"; d="scan'208";a="66312716" Received: from linksys13920.jf.intel.com (HELO rpedgeco-HP-Z240-Tower-Workstation.jf.intel.com) ([10.7.197.56]) by orsmga001.jf.intel.com with ESMTP; 20 Jun 2018 15:09:32 -0700 From: Rick Edgecombe To: tglx@linutronix.de, mingo@redhat.com, hpa@zytor.com, x86@kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, kernel-hardening@lists.openwall.com Cc: kristen.c.accardi@intel.com, dave.hansen@intel.com, arjan.van.de.ven@intel.com, Rick Edgecombe Subject: [PATCH 2/3] x86/modules: Increase randomization for modules Date: Wed, 20 Jun 2018 15:09:29 -0700 Message-Id: <1529532570-21765-3-git-send-email-rick.p.edgecombe@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1529532570-21765-1-git-send-email-rick.p.edgecombe@intel.com> References: <1529532570-21765-1-git-send-email-rick.p.edgecombe@intel.com> X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP This changes the behavior of the KASLR logic for allocating memory for the text sections of loadable modules. It randomizes the location of each module text section with about 18 bits of entropy in typical use. This is enabled on X86_64 only. For 32 bit, the behavior is unchanged. The algorithm evenly breaks the module space in two, a random area and a backup area. For module text allocations, it first tries to allocate up to 10 randomly located starting pages inside the random section. If this fails, it will allocate in the backup area. The backup area base will be offset in the same way as the current algorithm does for the base area, 1024 possible locations. Signed-off-by: Rick Edgecombe --- arch/x86/include/asm/pgtable_64_types.h | 1 + arch/x86/kernel/module.c | 80 ++++++++++++++++++++++++++++++--- 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h index 054765a..a98708a 100644 --- a/arch/x86/include/asm/pgtable_64_types.h +++ b/arch/x86/include/asm/pgtable_64_types.h @@ -141,6 +141,7 @@ extern unsigned int ptrs_per_p4d; /* The module sections ends with the start of the fixmap */ #define MODULES_END _AC(0xffffffffff000000, UL) #define MODULES_LEN (MODULES_END - MODULES_VADDR) +#define MODULES_RAND_LEN (MODULES_LEN/2) #define ESPFIX_PGD_ENTRY _AC(-2, UL) #define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << P4D_SHIFT) diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index f58336a..833ea81 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -77,6 +77,71 @@ static unsigned long int get_module_load_offset(void) } #endif +static unsigned long get_module_area_base(void) +{ + return MODULES_VADDR + get_module_load_offset(); +} + +#if defined(CONFIG_X86_64) && defined(CONFIG_RANDOMIZE_BASE) +static unsigned long get_module_vmalloc_start(void) +{ + if (kaslr_enabled()) + return MODULES_VADDR + MODULES_RAND_LEN + + get_module_load_offset(); + else + return get_module_area_base(); +} + +static void *try_module_alloc(unsigned long addr, unsigned long size) +{ + return __vmalloc_node_try_addr(addr, size, GFP_KERNEL, + PAGE_KERNEL_EXEC, 0, + NUMA_NO_NODE, + __builtin_return_address(0)); +} + +/* + * Try to allocate in 10 random positions starting in the random part of the + * module space. If these fail, return NULL. + */ +static void *try_module_randomize_each(unsigned long size) +{ + void *p = NULL; + unsigned int i; + unsigned long offset; + unsigned long addr; + unsigned long end; + const unsigned long nr_mod_positions = MODULES_RAND_LEN / MODULE_ALIGN; + + if (!kaslr_enabled()) + return NULL; + + for (i = 0; i < 10; i++) { + offset = (get_random_long() % nr_mod_positions) * MODULE_ALIGN; + addr = (unsigned long)MODULES_VADDR + offset; + end = addr + size; + + if (end > addr && end < MODULES_END) { + p = try_module_alloc(addr, size); + + if (p) + return p; + } + } + return NULL; +} +#else +static unsigned long get_module_vmalloc_start(void) +{ + return get_module_area_base(); +} + +static void *try_module_randomize_each(unsigned long size) +{ + return NULL; +} +#endif + void *module_alloc(unsigned long size) { void *p; @@ -84,11 +149,16 @@ void *module_alloc(unsigned long size) if (PAGE_ALIGN(size) > MODULES_LEN) return NULL; - p = __vmalloc_node_range(size, MODULE_ALIGN, - MODULES_VADDR + get_module_load_offset(), - MODULES_END, GFP_KERNEL, - PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE, - __builtin_return_address(0)); + p = try_module_randomize_each(size); + + if (!p) + p = __vmalloc_node_range(size, MODULE_ALIGN, + get_module_vmalloc_start(), + MODULES_END, GFP_KERNEL, + PAGE_KERNEL_EXEC, 0, + NUMA_NO_NODE, + __builtin_return_address(0)); + if (p && (kasan_module_alloc(p, size) < 0)) { vfree(p); return NULL;