From patchwork Sat Jul 7 00:35:43 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: 10512635 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 D55B5600CB for ; Sat, 7 Jul 2018 00:35:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5C0728701 for ; Sat, 7 Jul 2018 00:35:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B95992883A; Sat, 7 Jul 2018 00:35:36 +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 30DD228701 for ; Sat, 7 Jul 2018 00:35:36 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B41BB6B0006; Fri, 6 Jul 2018 20:35:30 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id A24976B0007; Fri, 6 Jul 2018 20:35:30 -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 8C3BE6B0008; Fri, 6 Jul 2018 20:35:30 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pf0-f198.google.com (mail-pf0-f198.google.com [209.85.192.198]) by kanga.kvack.org (Postfix) with ESMTP id 41EFF6B0007 for ; Fri, 6 Jul 2018 20:35:30 -0400 (EDT) Received: by mail-pf0-f198.google.com with SMTP id b17-v6so6561475pff.17 for ; Fri, 06 Jul 2018 17:35:30 -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=qkZVry6p40eE+4oFa/rJsjGOY8ood8Tzto55SQHMrHI=; b=n0f1EAtPmW1Y6h+JYsiFvw/CDsKU0zFB6erbyWewvmis0UVuKADMzyO2farDIOdPgd ElMA/5UDhF4essWAqypjdj6ONb9R2cHspfSdZm3Nrga+cfAaONfyd+8YkqmbiXPPWnSU dB+dcVHq1cgQ3c0x4Chw9M11PtiXtSd/j5VbwQnctaeN13VkZCN0D14guUPmuIpnrxCd fqF8F2xcImBlCHq9jwN8BQcyywHkR80HDWkHgr8GaJSSSoGtdmOXrKeIUO+VySvZAxF/ rhQnCoeC+xQnj1V5IVf5j6Ju9nHFmCqV+P0aALiCckdhUDuw+TBP2nhymdE7vuQV7MRt fCUQ== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of rick.p.edgecombe@intel.com designates 192.55.52.93 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: APt69E3IqPhSpnt6y63AI3eDLBhIrYD2hsXdkW6TgCh1h42bKGja3bG6 p/mGY/nUNhLUD/RSL976ieadbX/gLh7jCqxnQyRKcpREfD7fhClnsMTNvtmL/qrIzmp/Eow0959 TZOz7ONH5R7J+pJ2YjT5/TzCMRY/BuIONOF6cj2rsuay5A1OMjMqr6Zzi0E7bq9uiYA== X-Received: by 2002:a17:902:b08a:: with SMTP id p10-v6mr12376357plr.0.1530923729950; Fri, 06 Jul 2018 17:35:29 -0700 (PDT) X-Google-Smtp-Source: AAOMgpcvCbCHsfJH3Rwlz9XdK7lbfQOEGDBiClckv2ffBc3kAV1EE2Bz8aLE9YcqB6TiyTgHw5sx X-Received: by 2002:a17:902:b08a:: with SMTP id p10-v6mr12376331plr.0.1530923728883; Fri, 06 Jul 2018 17:35:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530923728; cv=none; d=google.com; s=arc-20160816; b=fhWc8/PSWFKl0wIBn5BYqREZD6nyydWHm0Gdl5Hvls7Vl3/8DD6I44Cu1RYIEHK3rv Dn2x7wvAi04exUIx2hs7xkYdJW9SiIUS0gf0fFrtJUIMKGJef148f+W4AW+0ruw2iccW VxichPhQ9vGoAySRRsdGQNYRRhF7nKvtnhzNJnIgEfyof1sfDz2KTbc7AxbxHM2PAjDR JjEf41w/3OcjOZpx2zzqLQrLpzlzDAunR7XlyHvNYFFDc5h5DcWzPehnUW4LIp6e3AQ5 QqSazQj6u2NWDPcG5MXdjaNANciD+VuzBmFi8ggCMP2g8PAcjY5ZOlOQ1pjZdMTiltju B2Qw== 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=qkZVry6p40eE+4oFa/rJsjGOY8ood8Tzto55SQHMrHI=; b=Odsl1dR4w2XlN515FUbU3MQ7S7cGmciM6tqsqQIQ7CyXUCUeF51lWr3OJ89LzRL8Ll 41edxycAna8z7sjurocf7VB0NeX9MvOc51Vhl3qRIEKdpvtVRVu14EWganATuF2vD41A PQPmmdxL+qfkDP7YdtWuZZWWtY9nxyclRTngUH133WihC64jDVVAxDXR91RHHqfNu9/D m9zC4IyxCXbiGNEhrEoPca1nlDW9K28FfQWycfty+RU5WUCAGrszKBxPmEIHyrGlcVsN lh5jdBRttuHzpXJT6uoDRAwgjZo8gx0XEP2WSCn6e4mv4VP58csrUq0NosOhaXVhwR0C DwKg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of rick.p.edgecombe@intel.com designates 192.55.52.93 as permitted sender) smtp.mailfrom=rick.p.edgecombe@intel.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from mga11.intel.com (mga11.intel.com. [192.55.52.93]) by mx.google.com with ESMTPS id 1-v6si9618339pla.509.2018.07.06.17.35.28 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 06 Jul 2018 17:35:28 -0700 (PDT) Received-SPF: pass (google.com: domain of rick.p.edgecombe@intel.com designates 192.55.52.93 as permitted sender) client-ip=192.55.52.93; Authentication-Results: mx.google.com; spf=pass (google.com: domain of rick.p.edgecombe@intel.com designates 192.55.52.93 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 orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Jul 2018 17:35:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,318,1526367600"; d="scan'208";a="238445485" Received: from linksys13920.jf.intel.com (HELO rpedgeco-HP-Z240-Tower-Workstation.jf.intel.com) ([10.7.197.56]) by orsmga005.jf.intel.com with ESMTP; 06 Jul 2018 17:35:28 -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@linux.intel.com, dave.hansen@intel.com, arjan@linux.intel.com, Rick Edgecombe Subject: [PATCH 2/3] x86/modules: Increase randomization for modules Date: Fri, 6 Jul 2018 17:35:43 -0700 Message-Id: <1530923744-25687-3-git-send-email-rick.p.edgecombe@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1530923744-25687-1-git-send-email-rick.p.edgecombe@intel.com> References: <1530923744-25687-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 17 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 at a number of 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 | 103 ++++++++++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h index 054765a..56452a0 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 PAGE_ALIGN((MODULES_LEN/3)*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..4ffff9f 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -77,6 +77,93 @@ 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, + int try_purge) +{ + return __vmalloc_node_try_addr(addr, size, GFP_KERNEL, + PAGE_KERNEL_EXEC, 0, + NUMA_NO_NODE, try_purge, + __builtin_return_address(0)); +} + +/* + * Try to allocate in the random area. First 5000 times without purging, then + * 5000 times with purging. 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; + unsigned long last_lazy_free_blocked = 0; + const unsigned long nr_mod_positions = MODULES_RAND_LEN / MODULE_ALIGN; + const unsigned long nr_try_purge = 5000; + const unsigned long nr_no_purge = 5000; + + if (!kaslr_enabled()) + return NULL; + + for (i = 0; i < nr_try_purge + nr_no_purge; 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) { + if (i < nr_no_purge) { + /* First try to avoid having to purge */ + p = try_module_alloc(addr, size, 0); + + /* + * Save the last value that was blocked by a + * lazy purge area + */ + if (IS_ERR(p) && PTR_ERR(p) == -EBUSY) + last_lazy_free_blocked = addr; + else if (p && !IS_ERR(p)) + return p; + } else { + /* Give up and allow for purges */ + if (i == nr_try_purge && last_lazy_free_blocked) + addr = last_lazy_free_blocked; + + p = try_module_alloc(addr, size, 1); + + 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,16 +171,20 @@ 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; } - return p; }