All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arvind Sankar <nivedita@alum.mit.edu>
To: Kees Cook <keescook@chromium.org>, x86@kernel.org
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH v2 4/8] x86/kaslr: Initialize mem_limit to the real maximum address
Date: Mon, 27 Jul 2020 19:07:57 -0400	[thread overview]
Message-ID: <20200727230801.3468620-5-nivedita@alum.mit.edu> (raw)
In-Reply-To: <20200727215047.3341098-1-nivedita@alum.mit.edu>

On 64-bit, the kernel must be placed below MAXMEM (64TiB with 4-level
paging or 4PiB with 5-level paging). This is currently not enforced by
KASLR, which thus implicitly relies on physical memory being limited to
less than 64TiB.

On 32-bit, the limit is KERNEL_IMAGE_SIZE (512MiB). This is enforced by
special checks in __process_mem_region.

Initialize mem_limit to the maximum (depending on architecture), instead
of ULLONG_MAX, and make sure the command-line arguments can only
decrease it. This makes the enforcement explicit on 64-bit, and
eliminates the 32-bit specific checks to keep the kernel below 512M.

Check upfront to make sure the minimum address is below the limit before
doing any work.

Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu>
---
 arch/x86/boot/compressed/kaslr.c | 41 +++++++++++++++++---------------
 1 file changed, 22 insertions(+), 19 deletions(-)

diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
index 207fcb7e7b71..758d78433f94 100644
--- a/arch/x86/boot/compressed/kaslr.c
+++ b/arch/x86/boot/compressed/kaslr.c
@@ -94,8 +94,11 @@ static unsigned long get_boot_seed(void)
 static bool memmap_too_large;
 
 
-/* Store memory limit specified by "mem=nn[KMG]" or "memmap=nn[KMG]" */
-static unsigned long long mem_limit = ULLONG_MAX;
+/*
+ * Store memory limit: MAXMEM on 64-bit and KERNEL_IMAGE_SIZE on 32-bit.
+ * It may be reduced by "mem=nn[KMG]" or "memmap=nn[KMG]" command line options.
+ */
+static unsigned long long mem_limit;
 
 /* Number of immovable memory regions */
 static int num_immovable_mem;
@@ -221,7 +224,7 @@ static void mem_avoid_memmap(enum parse_mode mode, char *str)
 
 		if (start == 0) {
 			/* Store the specified memory limit if size > 0 */
-			if (size > 0)
+			if (size > 0 && size < mem_limit)
 				mem_limit = size;
 
 			continue;
@@ -311,7 +314,8 @@ static void handle_mem_options(void)
 			if (mem_size == 0)
 				break;
 
-			mem_limit = mem_size;
+			if (mem_size < mem_limit)
+				mem_limit = mem_size;
 		} else if (!strcmp(param, "efi_fake_mem")) {
 			mem_avoid_memmap(PARSE_EFI, val);
 		}
@@ -322,7 +326,9 @@ static void handle_mem_options(void)
 }
 
 /*
- * In theory, KASLR can put the kernel anywhere in the range of [16M, 64T).
+ * In theory, KASLR can put the kernel anywhere in the range of [16M, MAXMEM)
+ * on 64-bit, and [16M, KERNEL_IMAGE_SIZE) on 32-bit.
+ *
  * The mem_avoid array is used to store the ranges that need to be avoided
  * when KASLR searches for an appropriate random address. We must avoid any
  * regions that are unsafe to overlap with during decompression, and other
@@ -619,10 +625,6 @@ static void __process_mem_region(struct mem_vector *entry,
 	unsigned long start_orig, end;
 	struct mem_vector cur_entry;
 
-	/* On 32-bit, ignore entries entirely above our maximum. */
-	if (IS_ENABLED(CONFIG_X86_32) && entry->start >= KERNEL_IMAGE_SIZE)
-		return;
-
 	/* Ignore entries entirely below our minimum. */
 	if (entry->start + entry->size < minimum)
 		return;
@@ -655,11 +657,6 @@ static void __process_mem_region(struct mem_vector *entry,
 		/* Reduce size by any delta from the original address. */
 		region.size -= region.start - start_orig;
 
-		/* On 32-bit, reduce region size to fit within max size. */
-		if (IS_ENABLED(CONFIG_X86_32) &&
-		    region.start + region.size > KERNEL_IMAGE_SIZE)
-			region.size = KERNEL_IMAGE_SIZE - region.start;
-
 		/* Return if region can't contain decompressed kernel */
 		if (region.size < image_size)
 			return;
@@ -844,15 +841,16 @@ static void process_e820_entries(unsigned long minimum,
 static unsigned long find_random_phys_addr(unsigned long minimum,
 					   unsigned long image_size)
 {
+	/* Bail out early if it's impossible to succeed. */
+	if (minimum + image_size > mem_limit)
+		return 0;
+
 	/* Check if we had too many memmaps. */
 	if (memmap_too_large) {
 		debug_putstr("Aborted memory entries scan (more than 4 memmap= args)!\n");
 		return 0;
 	}
 
-	/* Make sure minimum is aligned. */
-	minimum = ALIGN(minimum, CONFIG_PHYSICAL_ALIGN);
-
 	if (process_efi_entries(minimum, image_size))
 		return slots_fetch_random();
 
@@ -865,8 +863,6 @@ static unsigned long find_random_virt_addr(unsigned long minimum,
 {
 	unsigned long slots, random_addr;
 
-	/* Make sure minimum is aligned. */
-	minimum = ALIGN(minimum, CONFIG_PHYSICAL_ALIGN);
 	/* Align image_size for easy slot calculations. */
 	image_size = ALIGN(image_size, CONFIG_PHYSICAL_ALIGN);
 
@@ -913,6 +909,11 @@ void choose_random_location(unsigned long input,
 	/* Prepare to add new identity pagetables on demand. */
 	initialize_identity_maps();
 
+	if (IS_ENABLED(CONFIG_X86_32))
+		mem_limit = KERNEL_IMAGE_SIZE;
+	else
+		mem_limit = MAXMEM;
+
 	/* Record the various known unsafe memory ranges. */
 	mem_avoid_init(input, input_size, *output);
 
@@ -922,6 +923,8 @@ void choose_random_location(unsigned long input,
 	 * location:
 	 */
 	min_addr = min(*output, 512UL << 20);
+	/* Make sure minimum is aligned. */
+	min_addr = ALIGN(min_addr, CONFIG_PHYSICAL_ALIGN);
 
 	/* Walk available memory entries to find a random address. */
 	random_addr = find_random_phys_addr(min_addr, output_size);
-- 
2.26.2


  parent reply	other threads:[~2020-07-27 23:08 UTC|newest]

Thread overview: 91+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-27 21:50 [PATCH 0/8] x86/kaslr: Cleanup and small bugfixes Arvind Sankar
2020-07-27 21:50 ` [PATCH 1/8] x86/kaslr: Make command line handling safer Arvind Sankar
2020-07-27 21:50 ` [PATCH 2/8] x86/kaslr: Remove bogus warning and unnecessary goto Arvind Sankar
2020-07-27 21:50 ` [PATCH 3/8] x86/kaslr: Fix process_efi_entries comment Arvind Sankar
2020-07-27 21:50 ` [PATCH 4/8] x86/kaslr: Initialize mem_limit to the real maximum address Arvind Sankar
2020-07-27 21:50 ` [PATCH 5/8] x86/kaslr: Simplify __process_mem_region Arvind Sankar
2020-07-28 10:57   ` Ingo Molnar
2020-07-27 21:50 ` [PATCH 6/8] x86/kaslr: Simplify process_gb_huge_pages Arvind Sankar
2020-07-28 10:58   ` Ingo Molnar
2020-07-27 21:50 ` [PATCH 7/8] x86/kaslr: Clean up slot handling Arvind Sankar
2020-07-28 10:59   ` Ingo Molnar
2020-07-27 21:50 ` [PATCH 8/8] x86/kaslr: Don't use 64-bit mem_vector for 32-bit kernel Arvind Sankar
2020-07-28 11:05   ` Ingo Molnar
2020-07-27 23:07 ` [PATCH v2 0/8] x86/kaslr: Cleanup and small bugfixes Arvind Sankar
2020-07-28 11:06   ` Ingo Molnar
2020-07-28 14:24     ` Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 00/21] " Arvind Sankar
2020-07-30 18:02     ` Arvind Sankar
2020-07-31  9:21       ` Ingo Molnar
2020-07-31 23:33         ` Kees Cook
2020-08-03  1:15           ` [PATCH 0/1] x86/kaslr: Replace strlen with strnlen Arvind Sankar
2020-08-03  1:15             ` [PATCH 1/1] " Arvind Sankar
2020-08-06 23:38               ` [tip: x86/kaslr] x86/kaslr: Replace strlen() with strnlen() tip-bot2 for Arvind Sankar
2020-08-14 22:47           ` [PATCH v3 00/21] x86/kaslr: Cleanup and small bugfixes Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 01/21] x86/kaslr: Make command line handling safer Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 02/21] x86/kaslr: Remove bogus warning and unnecessary goto Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 03/21] x86/kaslr: Fix process_efi_entries comment Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 04/21] x86/kaslr: Initialize mem_limit to the real maximum address Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 05/21] x86/kaslr: Fix off-by-one error in __process_mem_region Arvind Sankar
2020-08-06 23:39     ` [tip: x86/kaslr] x86/kaslr: Fix off-by-one error in __process_mem_region() tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 06/21] x86/kaslr: Drop redundant cur_entry from __process_mem_region Arvind Sankar
2020-08-06 23:39     ` [tip: x86/kaslr] x86/kaslr: Drop redundant cur_entry from __process_mem_region() tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 07/21] x86/kaslr: Eliminate start_orig from __process_mem_region Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] x86/kaslr: Eliminate 'start_orig' local variable from __process_mem_region() tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 08/21] x86/kaslr: Drop redundant variable in __process_mem_region Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] x86/kaslr: Drop redundant variable in __process_mem_region() tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 09/21] x86/kaslr: Drop some redundant checks from __process_mem_region Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] x86/kaslr: Drop some redundant checks from __process_mem_region() tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 10/21] x86/kaslr: Fix off-by-one error in process_gb_huge_pages Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] x86/kaslr: Fix off-by-one error in process_gb_huge_pages() tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 11/21] x86/kaslr: Short-circuit gb_huge_pages on x86-32 Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] " tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 12/21] x86/kaslr: Simplify process_gb_huge_pages Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] x86/kaslr: Simplify process_gb_huge_pages() tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 13/21] x86/kaslr: Drop test for command-line parameters before parsing Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] " tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 14/21] x86/kaslr: Make the type of number of slots/slot areas consistent Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] " tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 15/21] x86/kaslr: Drop redundant check in store_slot_info Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] x86/kaslr: Drop redundant check in store_slot_info() tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 16/21] x86/kaslr: Drop unnecessary alignment in find_random_virt_addr Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] x86/kaslr: Drop unnecessary alignment in find_random_virt_addr() tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 17/21] x86/kaslr: Small cleanup of find_random_phys_addr Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] x86/kaslr: Small cleanup of find_random_phys_addr() tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 18/21] x86/kaslr: Make minimum/image_size unsigned long Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] x86/kaslr: Make minimum/image_size 'unsigned long' tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 19/21] x86/kaslr: Replace unsigned long long with u64 Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] x86/kaslr: Replace 'unsigned long long' with 'u64' tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 20/21] x86/kaslr: Make local variables 64-bit Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] " tip-bot2 for Arvind Sankar
2020-07-28 22:57   ` [PATCH v3 21/21] x86/kaslr: Add a check that the random address is in range Arvind Sankar
2020-08-06 23:38     ` [tip: x86/kaslr] " tip-bot2 for Arvind Sankar
2020-07-27 23:07 ` [PATCH v2 1/8] x86/kaslr: Make command line handling safer Arvind Sankar
2020-07-28 12:29   ` [tip: x86/kaslr] " tip-bot2 for Arvind Sankar
2020-07-28 18:26   ` [PATCH v2 1/8] " Kees Cook
2020-08-06 23:39   ` [tip: x86/kaslr] " tip-bot2 for Arvind Sankar
2020-07-27 23:07 ` [PATCH v2 2/8] x86/kaslr: Remove bogus warning and unnecessary goto Arvind Sankar
2020-07-28 12:29   ` [tip: x86/kaslr] " tip-bot2 for Arvind Sankar
2020-07-28 18:26   ` [PATCH v2 2/8] " Kees Cook
2020-08-06 23:39   ` [tip: x86/kaslr] " tip-bot2 for Arvind Sankar
2020-07-27 23:07 ` [PATCH v2 3/8] x86/kaslr: Fix process_efi_entries comment Arvind Sankar
2020-07-28 12:29   ` [tip: x86/kaslr] " tip-bot2 for Arvind Sankar
2020-07-28 18:27   ` [PATCH v2 3/8] " Kees Cook
2020-08-06 23:39   ` [tip: x86/kaslr] " tip-bot2 for Arvind Sankar
2020-07-27 23:07 ` Arvind Sankar [this message]
2020-07-28 12:29   ` [tip: x86/kaslr] x86/kaslr: Initialize mem_limit to the real maximum address tip-bot2 for Arvind Sankar
2020-07-28 18:49   ` [PATCH v2 4/8] " Kees Cook
2020-08-06 23:39   ` [tip: x86/kaslr] " tip-bot2 for Arvind Sankar
2020-07-27 23:07 ` [PATCH v2 5/8] x86/kaslr: Simplify __process_mem_region Arvind Sankar
2020-07-28 19:25   ` Kees Cook
2020-07-28 19:42     ` Arvind Sankar
2020-07-27 23:07 ` [PATCH v2 6/8] x86/kaslr: Simplify process_gb_huge_pages Arvind Sankar
2020-07-28 19:27   ` Kees Cook
2020-07-28 19:45     ` Arvind Sankar
2020-07-28 20:13       ` Kees Cook
2020-07-27 23:08 ` [PATCH v2 7/8] x86/kaslr: Clean up slot handling Arvind Sankar
2020-07-28 19:34   ` Kees Cook
2020-07-28 20:04     ` Arvind Sankar
2020-07-27 23:08 ` [PATCH v2 8/8] x86/kaslr: Don't use 64-bit mem_vector for 32-bit kernel Arvind Sankar
2020-07-28 19:37   ` Kees Cook
2020-07-28 20:08     ` Arvind Sankar

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=20200727230801.3468620-5-nivedita@alum.mit.edu \
    --to=nivedita@alum.mit.edu \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=x86@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.