Commit-ID:  25dfe4785332723f09311dcb7fd91015a60c022f
Gitweb:     http://git.kernel.org/tip/25dfe4785332723f09311dcb7fd91015a60c022f
Author:     Thomas Garnier <thgar...@google.com>
AuthorDate: Wed, 27 Jul 2016 08:59:56 -0700
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Wed, 10 Aug 2016 16:10:06 +0200

x86/mm/64: Enable KASLR for vmemmap memory region

Add vmemmap in the list of randomized memory regions.

The vmemmap region holds a representation of the physical memory (through
a struct page array). An attacker could use this region to disclose the
kernel memory layout (walking the page linked list).

Signed-off-by: Thomas Garnier <thgar...@google.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Cc: Andy Lutomirski <l...@kernel.org>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Brian Gerst <brge...@gmail.com>
Cc: Denys Vlasenko <dvlas...@redhat.com>
Cc: H. Peter Anvin <h...@zytor.com>
Cc: Josh Poimboeuf <jpoim...@redhat.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: kernel-harden...@lists.openwall.com
Link: 
http://lkml.kernel.org/r/1469635196-122447-1-git-send-email-thgar...@google.com
[ Minor edits. ]
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 arch/x86/include/asm/kaslr.h            |  1 +
 arch/x86/include/asm/pgtable_64_types.h |  4 +++-
 arch/x86/mm/kaslr.c                     | 26 ++++++++++++++++++++++++--
 3 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/kaslr.h b/arch/x86/include/asm/kaslr.h
index 2674ee3..1052a79 100644
--- a/arch/x86/include/asm/kaslr.h
+++ b/arch/x86/include/asm/kaslr.h
@@ -6,6 +6,7 @@ unsigned long kaslr_get_random_long(const char *purpose);
 #ifdef CONFIG_RANDOMIZE_MEMORY
 extern unsigned long page_offset_base;
 extern unsigned long vmalloc_base;
+extern unsigned long vmemmap_base;
 
 void kernel_randomize_memory(void);
 #else
diff --git a/arch/x86/include/asm/pgtable_64_types.h 
b/arch/x86/include/asm/pgtable_64_types.h
index 6fdef9e..3a26420 100644
--- a/arch/x86/include/asm/pgtable_64_types.h
+++ b/arch/x86/include/asm/pgtable_64_types.h
@@ -57,11 +57,13 @@ typedef struct { pteval_t pte; } pte_t;
 #define MAXMEM         _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL)
 #define VMALLOC_SIZE_TB        _AC(32, UL)
 #define __VMALLOC_BASE _AC(0xffffc90000000000, UL)
-#define VMEMMAP_START  _AC(0xffffea0000000000, UL)
+#define __VMEMMAP_BASE _AC(0xffffea0000000000, UL)
 #ifdef CONFIG_RANDOMIZE_MEMORY
 #define VMALLOC_START  vmalloc_base
+#define VMEMMAP_START  vmemmap_base
 #else
 #define VMALLOC_START  __VMALLOC_BASE
+#define VMEMMAP_START  __VMEMMAP_BASE
 #endif /* CONFIG_RANDOMIZE_MEMORY */
 #define VMALLOC_END    (VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))
 #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
diff --git a/arch/x86/mm/kaslr.c b/arch/x86/mm/kaslr.c
index ec8654f..aec03aa 100644
--- a/arch/x86/mm/kaslr.c
+++ b/arch/x86/mm/kaslr.c
@@ -40,17 +40,26 @@
  * You need to add an if/def entry if you introduce a new memory region
  * compatible with KASLR. Your entry must be in logical order with memory
  * layout. For example, ESPFIX is before EFI because its virtual address is
- * before. You also need to add a BUILD_BUG_ON in kernel_randomize_memory to
+ * before. You also need to add a BUILD_BUG_ON() in kernel_randomize_memory() 
to
  * ensure that this order is correct and won't be changed.
  */
 static const unsigned long vaddr_start = __PAGE_OFFSET_BASE;
-static const unsigned long vaddr_end = VMEMMAP_START;
+
+#if defined(CONFIG_X86_ESPFIX64)
+static const unsigned long vaddr_end = ESPFIX_BASE_ADDR;
+#elif defined(CONFIG_EFI)
+static const unsigned long vaddr_end = EFI_VA_START;
+#else
+static const unsigned long vaddr_end = __START_KERNEL_map;
+#endif
 
 /* Default values */
 unsigned long page_offset_base = __PAGE_OFFSET_BASE;
 EXPORT_SYMBOL(page_offset_base);
 unsigned long vmalloc_base = __VMALLOC_BASE;
 EXPORT_SYMBOL(vmalloc_base);
+unsigned long vmemmap_base = __VMEMMAP_BASE;
+EXPORT_SYMBOL(vmemmap_base);
 
 /*
  * Memory regions randomized by KASLR (except modules that use a separate logic
@@ -63,6 +72,7 @@ static __initdata struct kaslr_memory_region {
 } kaslr_regions[] = {
        { &page_offset_base, 64/* Maximum */ },
        { &vmalloc_base, VMALLOC_SIZE_TB },
+       { &vmemmap_base, 1 },
 };
 
 /* Get size in bytes used by the memory region */
@@ -89,6 +99,18 @@ void __init kernel_randomize_memory(void)
        struct rnd_state rand_state;
        unsigned long remain_entropy;
 
+       /*
+        * All these BUILD_BUG_ON checks ensures the memory layout is
+        * consistent with the vaddr_start/vaddr_end variables.
+        */
+       BUILD_BUG_ON(vaddr_start >= vaddr_end);
+       BUILD_BUG_ON(config_enabled(CONFIG_X86_ESPFIX64) &&
+                    vaddr_end >= EFI_VA_START);
+       BUILD_BUG_ON((config_enabled(CONFIG_X86_ESPFIX64) ||
+                     config_enabled(CONFIG_EFI)) &&
+                    vaddr_end >= __START_KERNEL_map);
+       BUILD_BUG_ON(vaddr_end > __START_KERNEL_map);
+
        if (!kaslr_memory_enabled())
                return;
 

Reply via email to