Patch "x86/efistub: Avoid placing the kernel below LOAD_PHYSICAL_ADDR" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    x86/efistub: Avoid placing the kernel below LOAD_PHYSICAL_ADDR

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     x86-efistub-avoid-placing-the-kernel-below-load_physical_addr.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.


>From stable+bounces-25908-greg=kroah.com@xxxxxxxxxxxxxxx Mon Mar  4 12:21:12 2024
From: Ard Biesheuvel <ardb+git@xxxxxxxxxx>
Date: Mon,  4 Mar 2024 12:19:53 +0100
Subject: x86/efistub: Avoid placing the kernel below LOAD_PHYSICAL_ADDR
To: stable@xxxxxxxxxxxxxxx
Cc: linux-efi@xxxxxxxxxxxxxxx, Ard Biesheuvel <ardb@xxxxxxxxxx>,  Tom Englund <tomenglund26@xxxxxxxxx>
Message-ID: <20240304111937.2556102-35-ardb+git@xxxxxxxxxx>

From: Ard Biesheuvel <ardb+git@xxxxxxxxxx>

From: Ard Biesheuvel <ardb@xxxxxxxxxx>

[ Commit 2f77465b05b1270c832b5e2ee27037672ad2a10a upstream ]

The EFI stub's kernel placement logic randomizes the physical placement
of the kernel by taking all available memory into account, and picking a
region at random, based on a random seed.

When KASLR is disabled, this seed is set to 0x0, and this results in the
lowest available region of memory to be selected for loading the kernel,
even if this is below LOAD_PHYSICAL_ADDR. Some of this memory is
typically reserved for the GFP_DMA region, to accommodate masters that
can only access the first 16 MiB of system memory.

Even if such devices are rare these days, we may still end up with a
warning in the kernel log, as reported by Tom:

 swapper/0: page allocation failure: order:10, mode:0xcc1(GFP_KERNEL|GFP_DMA), nodemask=(null),cpuset=/,mems_allowed=0

Fix this by tweaking the random allocation logic to accept a low bound
on the placement, and set it to LOAD_PHYSICAL_ADDR.

Fixes: a1b87d54f4e4 ("x86/efistub: Avoid legacy decompressor when doing EFI boot")
Reported-by: Tom Englund <tomenglund26@xxxxxxxxx>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218404
Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 drivers/firmware/efi/libstub/arm64-stub.c  |    2 +-
 drivers/firmware/efi/libstub/efistub.h     |    3 ++-
 drivers/firmware/efi/libstub/randomalloc.c |   12 +++++++-----
 drivers/firmware/efi/libstub/x86-stub.c    |    1 +
 4 files changed, 11 insertions(+), 7 deletions(-)

--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -181,7 +181,7 @@ efi_status_t handle_kernel_image(unsigne
 		 */
 		status = efi_random_alloc(*reserve_size, min_kimg_align,
 					  reserve_addr, phys_seed,
-					  EFI_LOADER_CODE, EFI_ALLOC_LIMIT);
+					  EFI_LOADER_CODE, 0, EFI_ALLOC_LIMIT);
 		if (status != EFI_SUCCESS)
 			efi_warn("efi_random_alloc() failed: 0x%lx\n", status);
 	} else {
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -906,7 +906,8 @@ efi_status_t efi_get_random_bytes(unsign
 
 efi_status_t efi_random_alloc(unsigned long size, unsigned long align,
 			      unsigned long *addr, unsigned long random_seed,
-			      int memory_type, unsigned long alloc_limit);
+			      int memory_type, unsigned long alloc_min,
+			      unsigned long alloc_max);
 
 efi_status_t efi_random_get_seed(void);
 
--- a/drivers/firmware/efi/libstub/randomalloc.c
+++ b/drivers/firmware/efi/libstub/randomalloc.c
@@ -17,7 +17,7 @@
 static unsigned long get_entry_num_slots(efi_memory_desc_t *md,
 					 unsigned long size,
 					 unsigned long align_shift,
-					 u64 alloc_limit)
+					 u64 alloc_min, u64 alloc_max)
 {
 	unsigned long align = 1UL << align_shift;
 	u64 first_slot, last_slot, region_end;
@@ -30,11 +30,11 @@ static unsigned long get_entry_num_slots
 		return 0;
 
 	region_end = min(md->phys_addr + md->num_pages * EFI_PAGE_SIZE - 1,
-			 alloc_limit);
+			 alloc_max);
 	if (region_end < size)
 		return 0;
 
-	first_slot = round_up(md->phys_addr, align);
+	first_slot = round_up(max(md->phys_addr, alloc_min), align);
 	last_slot = round_down(region_end - size + 1, align);
 
 	if (first_slot > last_slot)
@@ -56,7 +56,8 @@ efi_status_t efi_random_alloc(unsigned l
 			      unsigned long *addr,
 			      unsigned long random_seed,
 			      int memory_type,
-			      unsigned long alloc_limit)
+			      unsigned long alloc_min,
+			      unsigned long alloc_max)
 {
 	unsigned long total_slots = 0, target_slot;
 	unsigned long total_mirrored_slots = 0;
@@ -78,7 +79,8 @@ efi_status_t efi_random_alloc(unsigned l
 		efi_memory_desc_t *md = (void *)map->map + map_offset;
 		unsigned long slots;
 
-		slots = get_entry_num_slots(md, size, ilog2(align), alloc_limit);
+		slots = get_entry_num_slots(md, size, ilog2(align), alloc_min,
+					    alloc_max);
 		MD_NUM_SLOTS(md) = slots;
 		total_slots += slots;
 		if (md->attribute & EFI_MEMORY_MORE_RELIABLE)
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -785,6 +785,7 @@ static efi_status_t efi_decompress_kerne
 
 	status = efi_random_alloc(alloc_size, CONFIG_PHYSICAL_ALIGN, &addr,
 				  seed[0], EFI_LOADER_CODE,
+				  LOAD_PHYSICAL_ADDR,
 				  EFI_X86_KERNEL_ALLOC_LIMIT);
 	if (status != EFI_SUCCESS)
 		return status;


Patches currently in stable-queue which might be from kroah.com@xxxxxxxxxxxxxxx are

queue-6.1/x86-decompressor-avoid-magic-offsets-for-efi-handover-entrypoint.patch
queue-6.1/x86-efistub-avoid-placing-the-kernel-below-load_physical_addr.patch
queue-6.1/x86-efistub-avoid-legacy-decompressor-when-doing-efi-boot.patch
queue-6.1/x86-efistub-perform-4-5-level-paging-switch-from-the-stub.patch
queue-6.1/x86-boot-rename-conflicting-boot_params-pointer-to-boot_params_ptr.patch
queue-6.1/x86-efistub-perform-snp-feature-test-while-running-in-the-firmware.patch
queue-6.1/x86-efistub-simplify-and-clean-up-handover-entry-code.patch
queue-6.1/efi-libstub-add-memory-attribute-protocol-definitions.patch
queue-6.1/efi-libstub-add-limit-argument-to-efi_random_alloc.patch
queue-6.1/efi-x86-fix-the-missing-kaslr_flag-bit-in-boot_params-hdr.loadflags.patch
queue-6.1/arm64-efi-limit-allocations-to-48-bit-addressable-physical-region.patch
queue-6.1/x86-efistub-prefer-efi-memory-attributes-protocol-over-dxe-services.patch
queue-6.1/efi-efivars-prevent-double-registration.patch
queue-6.1/x86-boot-efistub-assign-global-boot_params-variable.patch
queue-6.1/x86-efistub-clear-bss-in-efi-handover-protocol-entrypoint.patch
queue-6.1/x86-decompressor-factor-out-kernel-decompression-and-relocation.patch
queue-6.1/efi-x86-avoid-physical-kaslr-on-older-dell-systems.patch




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux