linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Baoquan He <bhe@redhat.com>
To: tglx@linutronix.de, hpa@zytor.com, mingo@redhat.com
Cc: linux-kernel@vger.kernel.org, x86@kernel.org,
	keescook@chromium.org, yinghai@kernel.org, bp@suse.de,
	thgarnie@google.com, kuleshovmail@gmail.com, luto@kernel.org,
	mcgrof@kernel.org, anderson@redhat.com, dyoung@redhat.com,
	Baoquan He <bhe@redhat.com>
Subject: [PATCH v3 3/3] x86/64/KASLR: Determine the kernel mapping size at run time
Date: Wed,  4 Jan 2017 16:37:33 +0800	[thread overview]
Message-ID: <1483519053-23402-4-git-send-email-bhe@redhat.com> (raw)
In-Reply-To: <1483519053-23402-1-git-send-email-bhe@redhat.com>

Kernel behaviour is inconsistent between KASLR code is not compiled in
with CONFIG_RANDOMIZE_BASE disabled and user specifies "nokaslr" with
CONFIG_RANDOMIZE_BASE enabled. As long as CONFIG_RANDOMIZE_BASE is
enabled, kernel mapping size will be extended up another 512M to 1G
though "nokaslr" is specified explicitly. This is buggy.
CONFIG_RANDOMIZE_BASE should only decide if KASLR code need be compiled
in. If user specify "nokaslr", the kernel have to behave as no KASLR
code compiled in at all as expected.

The root cause of the inconsistency is KERNEL_MAPPING_SIZE, the size of
kernel image mapping area, is fixed at compiling time, and is changed
from 512M to 1G as long as CONFIG_RANDOMIZE_BASE is enabled.

So in this patch, change to determine the size of kernel image mapping
area at runtime. Though KASLR code compiled in, if "nokaslr" specified,
still make kernel mapping size be 512M.

Signed-off-by: Baoquan He <bhe@redhat.com>
Acked-by: Kees Cook <keescook@chromium.org>
---
 arch/x86/boot/compressed/kaslr.c     |  2 +-
 arch/x86/include/asm/kaslr.h         |  1 +
 arch/x86/include/asm/page_64_types.h |  6 +-----
 arch/x86/kernel/head64.c             | 11 ++++++-----
 arch/x86/mm/dump_pagetables.c        |  3 ++-
 5 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index 6ded03b..823f294 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -445,7 +445,7 @@ void choose_random_location(unsigned long input,
 	}
 
 #ifdef CONFIG_X86_64
-	_kernel_mapping_size = KERNEL_MAPPING_SIZE;
+	_kernel_mapping_size = KERNEL_MAPPING_SIZE_EXT;
 #endif
 
 	boot_params->hdr.loadflags |= KASLR_FLAG;
diff --git a/arch/x86/include/asm/kaslr.h b/arch/x86/include/asm/kaslr.h
index 1052a79..093935d 100644
--- a/arch/x86/include/asm/kaslr.h
+++ b/arch/x86/include/asm/kaslr.h
@@ -2,6 +2,7 @@
 #define _ASM_KASLR_H_
 
 unsigned long kaslr_get_random_long(const char *purpose);
+extern unsigned long kernel_mapping_size;
 
 #ifdef CONFIG_RANDOMIZE_MEMORY
 extern unsigned long page_offset_base;
diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h
index 20a5a9b..b8e79d7 100644
--- a/arch/x86/include/asm/page_64_types.h
+++ b/arch/x86/include/asm/page_64_types.h
@@ -64,10 +64,6 @@
  * kernel page table mapping, reducing the size of the modules area.
  */
 #define KERNEL_MAPPING_SIZE_EXT	(1024 * 1024 * 1024)
-#if defined(CONFIG_RANDOMIZE_BASE)
-#define KERNEL_MAPPING_SIZE	KERNEL_MAPPING_SIZE_EXT
-#else
-#define KERNEL_MAPPING_SIZE	KERNEL_IMAGE_SIZE
-#endif
+#define KERNEL_MAPPING_SIZE	kernel_mapping_size
 
 #endif /* _ASM_X86_PAGE_64_DEFS_H */
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 54a2372..46d2bd2 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -28,6 +28,7 @@
 #include <asm/bootparam_utils.h>
 #include <asm/microcode.h>
 #include <asm/kasan.h>
+#include <asm/cmdline.h>
 
 /*
  * Manage page tables very early on.
@@ -36,6 +37,7 @@ extern pgd_t early_level4_pgt[PTRS_PER_PGD];
 extern pmd_t early_dynamic_pgts[EARLY_DYNAMIC_PAGE_TABLES][PTRS_PER_PMD];
 static unsigned int __initdata next_early_pgt = 2;
 pmdval_t early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX);
+unsigned long kernel_mapping_size = KERNEL_IMAGE_SIZE;
 
 /* Wipe all early page tables except for the kernel symbol map */
 static void __init reset_early_page_tables(void)
@@ -138,12 +140,7 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
 	 * Build-time sanity checks on the kernel image and module
 	 * area mappings. (these are purely build-time and produce no code)
 	 */
-	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((__START_KERNEL_map & ~PMD_MASK) != 0);
-	BUILD_BUG_ON((MODULES_VADDR & ~PMD_MASK) != 0);
-	BUILD_BUG_ON(!(MODULES_VADDR > __START_KERNEL));
 	BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) ==
 				(__START_KERNEL & PGDIR_MASK)));
 	BUILD_BUG_ON(__fix_to_virt(__end_of_fixed_addresses) <= MODULES_END);
@@ -165,6 +162,10 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data)
 
 	copy_bootdata(__va(real_mode_data));
 
+	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) &&
+		!cmdline_find_option_bool(boot_command_line, "nokaslr"))
+		kernel_mapping_size = KERNEL_MAPPING_SIZE_EXT;
+
 	/*
 	 * Load microcode early on BSP.
 	 */
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index ea9c49a..412c3f5 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -82,7 +82,7 @@ static struct addr_marker address_markers[] = {
 	{ EFI_VA_END,		"EFI Runtime Services" },
 # endif
 	{ __START_KERNEL_map,   "High Kernel Mapping" },
-	{ MODULES_VADDR,        "Modules" },
+	{ 0/*MODULES_VADDR*/,        "Modules" },
 	{ MODULES_END,          "End Modules" },
 #else
 	{ PAGE_OFFSET,          "Kernel Mapping" },
@@ -442,6 +442,7 @@ static int __init pt_dump_init(void)
 	address_markers[LOW_KERNEL_NR].start_address = PAGE_OFFSET;
 	address_markers[VMALLOC_START_NR].start_address = VMALLOC_START;
 	address_markers[VMEMMAP_START_NR].start_address = VMEMMAP_START;
+	address_markers[MODULES_VADDR_NR].start_address = MODULES_VADDR;
 #endif
 #ifdef CONFIG_X86_32
 	address_markers[VMALLOC_START_NR].start_address = VMALLOC_START;
-- 
2.5.5

      parent reply	other threads:[~2017-01-04  8:50 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-04  8:37 [PATCH v3 0/3] Determine kernel image mapping size at runtime for x86_64 Baoquan He
2017-01-04  8:37 ` [PATCH v3 1/3] x86/64: Make kernel text mapping always take one whole page table in early boot code Baoquan He
2017-01-04 13:00   ` Boris Petkov
2017-01-05  3:28     ` Baoquan He
2017-01-05 14:01       ` Borislav Petkov
2017-01-05 19:35         ` Kees Cook
2017-01-05 20:52           ` Borislav Petkov
2017-01-06  9:35             ` Baoquan He
2017-01-04  8:37 ` [PATCH v3 2/3] x86/64: Introduce a new constant KERNEL_MAPPING_SIZE Baoquan He
2017-01-04  8:37 ` Baoquan He [this message]

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=1483519053-23402-4-git-send-email-bhe@redhat.com \
    --to=bhe@redhat.com \
    --cc=anderson@redhat.com \
    --cc=bp@suse.de \
    --cc=dyoung@redhat.com \
    --cc=hpa@zytor.com \
    --cc=keescook@chromium.org \
    --cc=kuleshovmail@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mcgrof@kernel.org \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=thgarnie@google.com \
    --cc=x86@kernel.org \
    --cc=yinghai@kernel.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).