All of lore.kernel.org
 help / color / mirror / Atom feed
From: Baoquan He <bhe@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: keescook@chromium.org, dave.jiang@intel.com,
	dan.j.williams@intel.com, hpa@zytor.com, tglx@linutronix.de,
	mingo@kernel.org, dyoung@redhat.com, Baoquan He <bhe@redhat.com>,
	Ingo Molnar <mingo@redhat.com>,
	x86@kernel.org, Yinghai Lu <yinghai@kernel.org>,
	Borislav Petkov <bp@suse.de>
Subject: [PATCH 3/4] KASLR: Handle memory limit specified by memmap and mem option
Date: Mon, 17 Apr 2017 21:34:58 +0800	[thread overview]
Message-ID: <1492436099-4017-4-git-send-email-bhe@redhat.com> (raw)
In-Reply-To: <1492436099-4017-1-git-send-email-bhe@redhat.com>

Option mem= will limit the max address system can use. Any memory
region above the limit will be removed. And memmap=nn[KMG] which
has no offset specified has the same behaviour as mem=. KASLR need
consider this when choose the random position for decompressing
kernel. Do it in this patch.

Signed-off-by: Baoquan He <bhe@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Cc: Kees Cook <keescook@chromium.org>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Borislav Petkov <bp@suse.de>
---
 arch/x86/boot/compressed/kaslr.c | 53 +++++++++++++++++++++++++++++++---------
 1 file changed, 42 insertions(+), 11 deletions(-)

diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index 36ab429..5361abd 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -67,6 +67,10 @@ int mem_avoid_memmap_index;
 extern unsigned long get_cmd_line_ptr(void);
 
 
+/* Store memory limit specified by "mem=nn[KMG]" or "memmap=nn[KMG]" */
+unsigned long long mem_limit = ULLONG_MAX;
+
+
 enum mem_avoid_index {
 	MEM_AVOID_ZO_RANGE = 0,
 	MEM_AVOID_INITRD,
@@ -117,15 +121,18 @@ parse_memmap(char *p, unsigned long long *start, unsigned long long *size)
 		return -EINVAL;
 
 	switch (*p) {
-	case '@':
-		/* Skip this region, usable */
-		*size = 0;
-		*start = 0;
 	case '#':
 	case '$':
 	case '!':
 		*start = memparse(p + 1, &p);
 		return 0;
+	case '@':
+		/* Skip this region, usable */
+		*size = 0;
+	default:
+		/* Avoid the region which is above the amount limit */
+		*start = 0;
+		return 0;
 	}
 
 	return -EINVAL;
@@ -151,9 +158,14 @@ static void mem_avoid_memmap(char *str)
 		if (rc < 0)
 			break;
 		str = k;
-		/* A usable region that should not be skipped */
-		if (size == 0)
+
+		if (start == 0) {
+			/* Store the specified memory limit if size > 0 */
+			if (size > 0)
+				mem_limit = size;
+
 			continue;
+		}
 
 		mem_avoid[MEM_AVOID_MEMMAP_BEGIN + i].start = start;
 		mem_avoid[MEM_AVOID_MEMMAP_BEGIN + i].size = size;
@@ -173,6 +185,7 @@ static int handle_mem_memmap(void)
 	char tmp_cmdline[COMMAND_LINE_SIZE];
 	size_t len = strlen((char *)args);
 	char *param, *val;
+	u64 mem_size;
 
 	len = (len >= COMMAND_LINE_SIZE) ? COMMAND_LINE_SIZE - 1 : len;
 	memcpy(tmp_cmdline, args, len);
@@ -195,8 +208,18 @@ static int handle_mem_memmap(void)
 			return -1;
 		}
 
-		if (!strcmp(param, "memmap"))
+		if (!strcmp(param, "memmap")) {
 			mem_avoid_memmap(val);
+		} else if (!strcmp(param, "mem")) {
+			char *p = val;
+
+			if (!strcmp(p, "nopentium"))
+				continue;
+			mem_size = memparse(p, &p);
+			if (mem_size == 0)
+				return -EINVAL;
+			mem_limit = mem_size;
+		}
 	}
 
 	return 0;
@@ -432,7 +455,8 @@ static void process_e820_entry(struct e820entry *entry,
 {
 	struct mem_vector region, overlap;
 	struct slot_area slot_area;
-	unsigned long start_orig;
+	unsigned long start_orig, end;
+	struct e820entry cur_entry;
 
 	/* Skip non-RAM entries. */
 	if (entry->type != E820_RAM)
@@ -446,8 +470,15 @@ static void process_e820_entry(struct e820entry *entry,
 	if (entry->addr + entry->size < minimum)
 		return;
 
-	region.start = entry->addr;
-	region.size = entry->size;
+	/* Ignore entries above memory limit */
+	end = min(entry->size + entry->addr - 1, mem_limit);
+	if (entry->addr >= end)
+		return;
+	cur_entry.addr = entry->addr;
+	cur_entry.size = end - entry->addr + 1;
+
+	region.start = cur_entry.addr;
+	region.size = cur_entry.size;
 
 	/* Give up if slot area array is full. */
 	while (slot_area_index < MAX_SLOT_AREA) {
@@ -461,7 +492,7 @@ static void process_e820_entry(struct e820entry *entry,
 		region.start = ALIGN(region.start, CONFIG_PHYSICAL_ALIGN);
 
 		/* Did we raise the address above this e820 region? */
-		if (region.start > entry->addr + entry->size)
+		if (region.start > cur_entry.addr + cur_entry.size)
 			return;
 
 		/* Reduce size by any delta from the original address. */
-- 
2.5.5

  parent reply	other threads:[~2017-04-17 13:35 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-17 13:34 [PATCH 0/4] Handle memmap and mem kernel options in boot stage kaslr Baoquan He
2017-04-17 13:34 ` [PATCH 1/4] param: Move function next_arg to lib/cmdline.c for later reuse Baoquan He
2017-04-18 12:51   ` [tip:x86/boot] boot/param: Move next_arg() function " tip-bot for Baoquan He
2017-04-18 20:17   ` [PATCH 1/4] param: Move function next_arg " Kees Cook
2017-04-17 13:34 ` [PATCH 2/4] KASLR: Parse all memmap entries in cmdline Baoquan He
2017-04-18 20:22   ` Kees Cook
2017-04-18 22:52     ` Baoquan He
2017-04-18 23:32       ` Kees Cook
2017-04-19  0:07         ` Baoquan He
2017-04-17 13:34 ` Baoquan He [this message]
2017-04-18 20:36   ` [PATCH 3/4] KASLR: Handle memory limit specified by memmap and mem option Kees Cook
2017-04-18 23:12     ` Baoquan He
2017-04-19  0:50     ` Baoquan He
2017-04-19  0:59       ` Baoquan He
2017-04-17 13:34 ` [PATCH 4/4] doc: Update description about memmap option in kernel-parameter.txt Baoquan He
2017-04-18  9:47 ` [PATCH 0/4] Handle memmap and mem kernel options in boot stage kaslr Ingo Molnar
2017-04-18 11:38   ` Baoquan He
2017-04-18 12:51     ` Ingo Molnar
2017-04-19  0:09       ` Baoquan He
2017-04-20 13:59       ` Baoquan He
2017-04-24  2:46       ` Baoquan He

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=1492436099-4017-4-git-send-email-bhe@redhat.com \
    --to=bhe@redhat.com \
    --cc=bp@suse.de \
    --cc=dan.j.williams@intel.com \
    --cc=dave.jiang@intel.com \
    --cc=dyoung@redhat.com \
    --cc=hpa@zytor.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.