linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: tip-bot for Yinghai Lu <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: peterz@infradead.org, vgoyal@redhat.com, bhe@redhat.com,
	mingo@kernel.org, dvlasenk@redhat.com, tglx@linutronix.de,
	brgerst@gmail.com, yinghai@kernel.org, bp@alien8.de,
	hpa@zytor.com, dyoung@redhat.com, keescook@chromium.org,
	luto@amacapital.net, torvalds@linux-foundation.org,
	akpm@linux-foundation.org, linux-kernel@vger.kernel.org,
	luto@kernel.org
Subject: [tip:x86/boot] x86/KASLR: Consolidate mem_avoid[] entries
Date: Fri, 6 May 2016 00:46:05 -0700	[thread overview]
Message-ID: <tip-9dc1969c24eff8b7d7a9a565d1047b624921ba06@git.kernel.org> (raw)
In-Reply-To: <1462486436-3707-3-git-send-email-keescook@chromium.org>

Commit-ID:  9dc1969c24eff8b7d7a9a565d1047b624921ba06
Gitweb:     http://git.kernel.org/tip/9dc1969c24eff8b7d7a9a565d1047b624921ba06
Author:     Yinghai Lu <yinghai@kernel.org>
AuthorDate: Thu, 5 May 2016 15:13:47 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 6 May 2016 09:00:59 +0200

x86/KASLR: Consolidate mem_avoid[] entries

The mem_avoid[] array is used to track positions that should be avoided (like
the compressed kernel, decompression code, etc) when selecting a memory
position for the randomly relocated kernel. Since ZO is now at the end of
the decompression buffer and the decompression code (and its heap and
stack) are at the front, we can safely consolidate the decompression entry,
the heap entry, and the stack entry. The boot_params memory, however, could
be elsewhere, so it should be explicitly included.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Baoquan He <bhe@redhat.com>
[ Rwrote changelog, cleaned up code comments. ]
Signed-off-by: Kees Cook <keescook@chromium.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: kernel-hardening@lists.openwall.com
Cc: lasse.collin@tukaani.org
Link: http://lkml.kernel.org/r/1462486436-3707-3-git-send-email-keescook@chromium.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/boot/compressed/kaslr.c | 77 +++++++++++++++++++++++++++++++---------
 1 file changed, 61 insertions(+), 16 deletions(-)

diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index 2072d82..6392f00 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -121,7 +121,7 @@ struct mem_vector {
 	unsigned long size;
 };
 
-#define MEM_AVOID_MAX 5
+#define MEM_AVOID_MAX 4
 static struct mem_vector mem_avoid[MEM_AVOID_MAX];
 
 static bool mem_contains(struct mem_vector *region, struct mem_vector *item)
@@ -146,22 +146,71 @@ static bool mem_overlaps(struct mem_vector *one, struct mem_vector *two)
 	return true;
 }
 
+/*
+ * In theroy, KASLR can put the kernel anywhere in area of [16M, 64T). The
+ * mem_avoid array is used to store the ranges that need to be avoided when
+ * KASLR searches for a an appropriate random address. We must avoid any
+ * regions that are unsafe to overlap with during decompression, and other
+ * things like the initrd, cmdline and boot_params.
+ *
+ * How to calculate the unsafe areas is detailed here, and is informed by
+ * the decompression calculations in header.S, and the diagram in misc.c.
+ *
+ * The compressed vmlinux (ZO) plus relocs and the run space of ZO can't be
+ * overwritten by decompression output.
+ *
+ * ZO sits against the end of the decompression buffer, so we can calculate
+ * where text, data, bss, etc of ZO are positioned.
+ *
+ * The follow are already enforced by the code:
+ *  - init_size >= kernel_total_size
+ *  - input + input_len >= output + output_len
+ *  - kernel_total_size could be >= or < output_len
+ *
+ * From this, we can make several observations, illustrated by a diagram:
+ *  - init_size >= kernel_total_size
+ *  - input + input_len > output + output_len
+ *  - kernel_total_size >= output_len
+ *
+ * 0   output            input            input+input_len    output+init_size
+ * |     |                 |                       |                       |
+ * |     |                 |                       |                       |
+ * |-----|--------|--------|------------------|----|------------|----------|
+ *                |                           |                 |
+ *                |                           |                 |
+ * output+init_size-ZO_INIT_SIZE   output+output_len  output+kernel_total_size
+ *
+ * [output, output+init_size) is for the buffer for decompressing the
+ * compressed kernel (ZO).
+ *
+ * [output, output+kernel_total_size) is for the uncompressed kernel (VO)
+ * and its bss, brk, etc.
+ * [output, output+output_len) is VO plus relocs
+ *
+ * [output+init_size-ZO_INIT_SIZE, output+init_size) is the copied ZO.
+ * [input, input+input_len) is the copied compressed (VO (vmlinux after
+ * objcopy) plus relocs), not the ZO.
+ *
+ * [input+input_len, output+init_size) is [_text, _end) for ZO. That was the
+ * first range in mem_avoid, which included ZO's heap and stack. Also
+ * [input, input+input_size) need be put in mem_avoid array, but since it
+ * is adjacent to the first entry, they can be merged. This is how we get
+ * the first entry in mem_avoid[].
+ */
 static void mem_avoid_init(unsigned long input, unsigned long input_size,
-			   unsigned long output, unsigned long output_size)
+			   unsigned long output)
 {
+	unsigned long init_size = boot_params->hdr.init_size;
 	u64 initrd_start, initrd_size;
 	u64 cmd_line, cmd_line_size;
-	unsigned long unsafe, unsafe_len;
 	char *ptr;
 
 	/*
 	 * Avoid the region that is unsafe to overlap during
-	 * decompression (see calculations in ../header.S).
+	 * decompression.
 	 */
-	unsafe_len = (output_size >> 12) + 32768 + 18;
-	unsafe = (unsigned long)input + input_size - unsafe_len;
-	mem_avoid[0].start = unsafe;
-	mem_avoid[0].size = unsafe_len;
+	mem_avoid[0].start = input;
+	mem_avoid[0].size = (output + init_size) - input;
 
 	/* Avoid initrd. */
 	initrd_start  = (u64)boot_params->ext_ramdisk_image << 32;
@@ -181,13 +230,9 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size,
 	mem_avoid[2].start = cmd_line;
 	mem_avoid[2].size = cmd_line_size;
 
-	/* Avoid heap memory. */
-	mem_avoid[3].start = (unsigned long)free_mem_ptr;
-	mem_avoid[3].size = BOOT_HEAP_SIZE;
-
-	/* Avoid stack memory. */
-	mem_avoid[4].start = (unsigned long)free_mem_end_ptr;
-	mem_avoid[4].size = BOOT_STACK_SIZE;
+	/* Avoid params */
+	mem_avoid[3].start = (unsigned long)boot_params;
+	mem_avoid[3].size = sizeof(*boot_params);
 }
 
 /* Does this memory vector overlap a known avoided area? */
@@ -337,7 +382,7 @@ unsigned char *choose_random_location(unsigned char *input_ptr,
 	boot_params->hdr.loadflags |= KASLR_FLAG;
 
 	/* Record the various known unsafe memory ranges. */
-	mem_avoid_init(input, input_size, output, output_size);
+	mem_avoid_init(input, input_size, output);
 
 	/* Walk e820 and find a random address. */
 	random_addr = find_random_addr(output, output_size);

  reply	other threads:[~2016-05-06  7:47 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-05 22:13 [PATCH v6 0/11] x86/KASLR: Randomize virtual address separately Kees Cook
2016-05-05 22:13 ` [PATCH v6 01/11] x86/boot: Clean up pointer casting Kees Cook
2016-05-06  7:45   ` [tip:x86/boot] " tip-bot for Kees Cook
2016-05-06  8:53     ` Borislav Petkov
2016-05-06 10:10       ` Ingo Molnar
2016-05-06 15:21         ` Kees Cook
2016-05-06 10:36       ` Ingo Molnar
2016-05-06 10:44         ` Borislav Petkov
2016-05-06 11:50           ` [PATCH -v1.1] x86/boot: Simplify pointer casting in choose_random_location() Borislav Petkov
2016-05-07  6:35             ` [tip:x86/boot] " tip-bot for Borislav Petkov
2016-05-05 22:13 ` [PATCH v6 02/11] x86/KASLR: Consolidate mem_avoid entries Kees Cook
2016-05-06  7:46   ` tip-bot for Yinghai Lu [this message]
2016-05-06 16:08     ` [tip:x86/boot] x86/KASLR: Consolidate mem_avoid[] entries Borislav Petkov
2016-05-06 18:16       ` Kees Cook
2016-05-06 19:29         ` Borislav Petkov
2016-05-05 22:13 ` [PATCH v6 03/11] x86/boot: Split out kernel_ident_mapping_init Kees Cook
2016-05-05 22:13 ` [PATCH v6 04/11] x86/KASLR: Build identity mappings on demand Kees Cook
2016-05-06  7:00   ` Ingo Molnar
2016-05-06 17:44     ` Kees Cook
2016-05-05 22:13 ` [PATCH v6 05/11] x86/KASLR: Add slot_area to manage random_addr slots Kees Cook
2016-05-05 22:13 ` [PATCH v6 06/11] x86/KASLR: Return earliest overlap when avoiding regions Kees Cook
2016-05-05 22:13 ` [PATCH v6 07/11] x86/KASLR: Add virtual address choosing function Kees Cook
2016-05-05 22:13 ` [PATCH v6 08/11] x86/KASLR: Clarify purpose of each get_random_long Kees Cook
2016-05-05 22:13 ` [PATCH v6 09/11] x86/KASLR: Randomize virtual address separately Kees Cook
2016-05-05 22:13 ` [PATCH v6 10/11] x86/KASLR: Add physical address randomization >4G Kees Cook
2016-05-06  8:27   ` Baoquan He
2016-05-06 15:31     ` Kees Cook
2016-05-08  9:17       ` Baoquan He
2016-05-05 22:13 ` [PATCH v6 11/11] x86/KASLR: Allow randomization below load address Kees Cook

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=tip-9dc1969c24eff8b7d7a9a565d1047b624921ba06@git.kernel.org \
    --to=tipbot@zytor.com \
    --cc=akpm@linux-foundation.org \
    --cc=bhe@redhat.com \
    --cc=bp@alien8.de \
    --cc=brgerst@gmail.com \
    --cc=dvlasenk@redhat.com \
    --cc=dyoung@redhat.com \
    --cc=hpa@zytor.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=luto@kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=vgoyal@redhat.com \
    --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).