linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: ard.biesheuvel@linaro.org (Ard Biesheuvel)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] arm64: allow the module region to be randomized independently
Date: Mon,  8 Feb 2016 11:12:12 +0100	[thread overview]
Message-ID: <1454926332-25929-1-git-send-email-ard.biesheuvel@linaro.org> (raw)
In-Reply-To: <CAGXu5j+1rcScYedzQ5o0aaGZJWPCBGk-gai0D8jY8Huc-VuG7A@mail.gmail.com>

This patch applies directly onto '[PATCH v5sub2 7/8] arm64: add support for
kernel ASLR' so it can be folded in or applied separately, as desired.

As pointed out by Kees, fully randomizing each module allocation does not add
anything in terms of security, and only hurts performance even more, since it
would cause all inter-module branches to be resolved via veneers as well.

----------8<--------------
This adds the option to randomize the module region independently from the
core kernel, and enables it by default. This makes it less likely that the
location of core kernel data structures can be determined by an adversary,
but causes all function calls from modules into the core kernel to be
resolved via entries in the module PLTs.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 arch/arm64/Kconfig              | 15 ++++++++
 arch/arm64/include/asm/module.h |  6 ++++
 arch/arm64/kernel/kaslr.c       | 36 +++++++++++++++-----
 arch/arm64/kernel/module.c      |  9 ++---
 4 files changed, 50 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index e3049d5c1246..666aacc4c763 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -787,6 +787,21 @@ config RANDOMIZE_BASE
 
 	  If unsure, say N.
 
+config RANDOMIZE_MODULE_REGION_FULL
+	bool "Randomize the module region independently from the core kernel"
+	depends on RANDOMIZE_BASE
+	default y
+	help
+	  Randomizes the location of the module region without considering the
+	  location of the core kernel. This way, it is impossible for modules
+	  to leak information about the location of core kernel data structures
+	  but it does imply that function calls between modules and the core
+	  kernel will need to be resolved via veneers in the module PLT.
+
+	  When this option is not set, the module region will be randomized over
+	  a limited range that contains the [_stext, _etext] interval of the
+	  core kernel, so branch relocations are always in range.
+
 endmenu
 
 menu "Boot options"
diff --git a/arch/arm64/include/asm/module.h b/arch/arm64/include/asm/module.h
index 8652fb613304..e12af6754634 100644
--- a/arch/arm64/include/asm/module.h
+++ b/arch/arm64/include/asm/module.h
@@ -31,4 +31,10 @@ struct mod_arch_specific {
 u64 module_emit_plt_entry(struct module *mod, const Elf64_Rela *rela,
 			  Elf64_Sym *sym);
 
+#ifdef CONFIG_RANDOMIZE_BASE
+extern u64 module_alloc_base;
+#else
+#define module_alloc_base	((u64)_etext - MODULES_VSIZE)
+#endif
+
 #endif /* __ASM_MODULE_H */
diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
index b0bf628ba51f..7a40aa4ba93d 100644
--- a/arch/arm64/kernel/kaslr.c
+++ b/arch/arm64/kernel/kaslr.c
@@ -20,7 +20,7 @@
 #include <asm/pgtable.h>
 #include <asm/sections.h>
 
-u32 __read_mostly module_load_offset;
+u64 __read_mostly module_alloc_base;
 
 static __init u64 get_kaslr_seed(void *fdt)
 {
@@ -126,14 +126,32 @@ u64 __init kaslr_early_init(u64 dt_phys)
 	    (((u64)_end + offset) >> SWAPPER_TABLE_SHIFT))
 		offset = (offset + (u64)(_end - _text)) & mask;
 
-	/*
-	 * Randomize the module region, by setting module_load_offset to
-	 * a PAGE_SIZE multiple in the interval [0, module_range). This
-	 * ensures that the resulting region still covers [_stext, _etext],
-	 * and that all relative branches can be resolved without veneers.
-	 */
-	module_range = MODULES_VSIZE - (u64)(_etext - _stext);
-	module_load_offset = ((module_range * (u16)seed) >> 16) & PAGE_MASK;
+	if (IS_ENABLED(CONFIG_RANDOMIZE_MODULE_REGION_FULL)) {
+		/*
+		 * Randomize the module region independently from the core
+		 * kernel. This prevents modules from leaking any information
+		 * about the address of the kernel itself, but results in
+		 * branches between modules and the core kernel that are
+		 * resolved via PLTs. (Branches between modules will be
+		 * resolved normally.)
+		 */
+		module_range = VMALLOC_END - VMALLOC_START - MODULES_VSIZE;
+		module_alloc_base = VMALLOC_START;
+	} else {
+		/*
+		 * Randomize the module region by setting module_alloc_base to
+		 * a PAGE_SIZE multiple in the range [_etext - MODULES_VSIZE,
+		 * _stext) . This guarantees that the resulting region still
+		 * covers [_stext, _etext], and that all relative branches can
+		 * be resolved without veneers.
+		 */
+		module_range = MODULES_VSIZE - (u64)(_etext - _stext);
+		module_alloc_base = (u64)_etext + offset - MODULES_VSIZE;
+	}
+
+	/* use the lower 21 bits to randomize the base of the module region */
+	module_alloc_base += (module_range * (seed & ((1 << 21) - 1))) >> 21;
+	module_alloc_base &= PAGE_MASK;
 
 	return offset;
 }
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index 54702d456680..dfa1ffaa9844 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -33,14 +33,9 @@
 void *module_alloc(unsigned long size)
 {
 	void *p;
-	u64 base = (u64)_etext - MODULES_VSIZE;
 
-	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
-		extern u32 module_load_offset;
-		base += module_load_offset;
-	}
-
-	p = __vmalloc_node_range(size, MODULE_ALIGN, base, base + MODULES_VSIZE,
+	p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
+				module_alloc_base + MODULES_VSIZE,
 				GFP_KERNEL, PAGE_KERNEL_EXEC, 0,
 				NUMA_NO_NODE, __builtin_return_address(0));
 
-- 
2.5.0

  reply	other threads:[~2016-02-08 10:12 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-01 13:09 [PATCH v5sub2 0/8] arm64: implement virtual KASLR Ard Biesheuvel
2016-02-01 13:09 ` [PATCH v5sub2 1/8] arm64: add support for module PLTs Ard Biesheuvel
2016-02-04 15:13   ` Catalin Marinas
2016-02-04 15:31     ` Ard Biesheuvel
2016-02-05 15:42       ` Catalin Marinas
2016-02-05 15:53         ` Ard Biesheuvel
2016-02-05 16:00           ` Catalin Marinas
2016-02-05 16:20             ` Ard Biesheuvel
2016-02-05 16:46               ` Catalin Marinas
2016-02-05 16:54                 ` Ard Biesheuvel
2016-02-05 17:21                   ` Catalin Marinas
2016-02-05 20:39                   ` Kees Cook
2016-02-08 10:12                     ` Ard Biesheuvel [this message]
2016-02-08 18:13                       ` [PATCH] arm64: allow the module region to be randomized independently Catalin Marinas
2016-02-08 18:29                         ` Ard Biesheuvel
2016-02-09 10:03                         ` Ard Biesheuvel
2016-02-09 10:45                           ` Catalin Marinas
2016-02-25 16:07   ` [PATCH v5sub2 1/8] arm64: add support for module PLTs Will Deacon
2016-02-25 16:12     ` Ard Biesheuvel
2016-02-25 16:13       ` Ard Biesheuvel
2016-02-25 16:26       ` Will Deacon
2016-02-25 16:33         ` Ard Biesheuvel
2016-02-25 16:42           ` Will Deacon
2016-02-25 16:43             ` Ard Biesheuvel
2016-02-25 16:46               ` Will Deacon
2016-02-25 16:49                 ` Ard Biesheuvel
2016-02-25 16:50                   ` Ard Biesheuvel
2016-02-25 16:56                     ` Will Deacon
2016-02-25 17:31                       ` Ard Biesheuvel
2016-02-25 18:29                         ` Will Deacon
2016-02-01 13:09 ` [PATCH v5sub2 2/8] arm64: avoid R_AARCH64_ABS64 relocations for Image header fields Ard Biesheuvel
2016-02-01 13:09 ` [PATCH v5sub2 3/8] arm64: avoid dynamic relocations in early boot code Ard Biesheuvel
2016-02-01 13:09 ` [PATCH v5sub2 4/8] arm64: make asm/elf.h available to asm files Ard Biesheuvel
2016-02-01 13:09 ` [PATCH v5sub2 5/8] scripts/sortextable: add support for ET_DYN binaries Ard Biesheuvel
2016-02-01 13:09 ` [PATCH v5sub2 6/8] arm64: add support for building vmlinux as a relocatable PIE binary Ard Biesheuvel
2016-02-01 13:09 ` [PATCH v5sub2 7/8] arm64: add support for kernel ASLR Ard Biesheuvel
2016-02-01 13:09 ` [PATCH v5sub2 8/8] arm64: kaslr: randomize the linear region Ard Biesheuvel
2016-02-01 13:35 ` [PATCH v5sub2 0/8] arm64: implement virtual KASLR Ard Biesheuvel
2016-02-05 17:32   ` Catalin Marinas
2016-02-05 17:38     ` Ard Biesheuvel
2016-02-05 17:46       ` Catalin Marinas
2016-02-05 20:42       ` Kees Cook
2016-02-08 12:14         ` Catalin Marinas
2016-02-08 14:30           ` Ard Biesheuvel
2016-02-08 16:19             ` Catalin Marinas
2016-02-08 16:20               ` Ard Biesheuvel
2016-02-08 16:46                 ` Catalin Marinas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1454926332-25929-1-git-send-email-ard.biesheuvel@linaro.org \
    --to=ard.biesheuvel@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).