Skip to content

Commit 253807f

Browse files
committed
x86/efistub: Omit physical KASLR when memory reservations exist
JIRA: https://issues.redhat.com/browse/RHEL-83461 This patch is a backport of the following upstream commit: commit 15aa8fb Author: Ard Biesheuvel <ardb@kernel.org> Date: Thu May 16 11:05:42 2024 +0200 x86/efistub: Omit physical KASLR when memory reservations exist The legacy decompressor has elaborate logic to ensure that the randomized physical placement of the decompressed kernel image does not conflict with any memory reservations, including ones specified on the command line using mem=, memmap=, efi_fake_mem= or hugepages=, which are taken into account by the kernel proper at a later stage. When booting in EFI mode, it is the firmware's job to ensure that the chosen range does not conflict with any memory reservations that it knows about, and this is trivially achieved by using the firmware's memory allocation APIs. That leaves reservations specified on the command line, though, which the firmware knows nothing about, as these regions have no other special significance to the platform. Since commit a1b87d5 ("x86/efistub: Avoid legacy decompressor when doing EFI boot") these reservations are not taken into account when randomizing the physical placement, which may result in conflicts where the memory cannot be reserved by the kernel proper because its own executable image resides there. To avoid having to duplicate or reuse the existing complicated logic, disable physical KASLR entirely when such overrides are specified. These are mostly diagnostic tools or niche features, and physical KASLR (as opposed to virtual KASLR, which is much more important as it affects the memory addresses observed by code executing in the kernel) is something we can live without. Closes: https://lkml.kernel.org/r/FA5F6719-8824-4B04-803E-82990E65E627%40akamai.com Reported-by: Ben Chaney <bchaney@akamai.com> Fixes: a1b87d5 ("x86/efistub: Avoid legacy decompressor when doing EFI boot") Cc: <stable@vger.kernel.org> # v6.1+ Reviewed-by: Kees Cook <keescook@chromium.org> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Charles Haithcock <chaithco@redhat.com>
1 parent 2c415ad commit 253807f

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

drivers/firmware/efi/libstub/x86-stub.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,26 @@ static void error(char *str)
770770
efi_warn("Decompression failed: %s\n", str);
771771
}
772772

773+
static const char *cmdline_memmap_override;
774+
775+
static efi_status_t parse_options(const char *cmdline)
776+
{
777+
static const char opts[][14] = {
778+
"mem=", "memmap=", "efi_fake_mem=", "hugepages="
779+
};
780+
781+
for (int i = 0; i < ARRAY_SIZE(opts); i++) {
782+
const char *p = strstr(cmdline, opts[i]);
783+
784+
if (p == cmdline || (p > cmdline && isspace(p[-1]))) {
785+
cmdline_memmap_override = opts[i];
786+
break;
787+
}
788+
}
789+
790+
return efi_parse_options(cmdline);
791+
}
792+
773793
static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry)
774794
{
775795
unsigned long virt_addr = LOAD_PHYSICAL_ADDR;
@@ -801,6 +821,10 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry)
801821
!memcmp(efistub_fw_vendor(), ami, sizeof(ami))) {
802822
efi_debug("AMI firmware v2.0 or older detected - disabling physical KASLR\n");
803823
seed[0] = 0;
824+
} else if (cmdline_memmap_override) {
825+
efi_info("%s detected on the kernel command line - disabling physical KASLR\n",
826+
cmdline_memmap_override);
827+
seed[0] = 0;
804828
}
805829

806830
boot_params_ptr->hdr.loadflags |= KASLR_FLAG;
@@ -877,7 +901,7 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
877901
}
878902

879903
#ifdef CONFIG_CMDLINE_BOOL
880-
status = efi_parse_options(CONFIG_CMDLINE);
904+
status = parse_options(CONFIG_CMDLINE);
881905
if (status != EFI_SUCCESS) {
882906
efi_err("Failed to parse options\n");
883907
goto fail;
@@ -886,7 +910,7 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
886910
if (!IS_ENABLED(CONFIG_CMDLINE_OVERRIDE)) {
887911
unsigned long cmdline_paddr = ((u64)hdr->cmd_line_ptr |
888912
((u64)boot_params->ext_cmd_line_ptr << 32));
889-
status = efi_parse_options((char *)cmdline_paddr);
913+
status = parse_options((char *)cmdline_paddr);
890914
if (status != EFI_SUCCESS) {
891915
efi_err("Failed to parse options\n");
892916
goto fail;

0 commit comments

Comments
 (0)