aboutsummaryrefslogtreecommitdiff
path: root/arch/x86/kernel/kexec-bzimage64.c
diff options
context:
space:
mode:
authorGravatar Chris Koch <chrisko@google.com> 2023-12-15 11:05:21 -0800
committerGravatar Dave Hansen <dave.hansen@linux.intel.com> 2024-02-22 15:13:57 -0800
commit43b1d3e68ee7f41c494ee5558d8def3d3d0b7f1b (patch)
tree659553db237015c70de48d9b6c71b81e1a4f8723 /arch/x86/kernel/kexec-bzimage64.c
parentx86/boot: Add a message about ignored early NMIs (diff)
downloadlinux-43b1d3e68ee7f41c494ee5558d8def3d3d0b7f1b.tar.gz
linux-43b1d3e68ee7f41c494ee5558d8def3d3d0b7f1b.tar.bz2
linux-43b1d3e68ee7f41c494ee5558d8def3d3d0b7f1b.zip
kexec: Allocate kernel above bzImage's pref_address
A relocatable kernel will relocate itself to pref_address if it is loaded below pref_address. This means a booted kernel may be relocating itself to an area with reserved memory on modern systems, potentially clobbering arbitrary data that may be important to the system. This is often the case, as the default value of PHYSICAL_START is 0x1000000 and kernels are typically loaded at 0x100000 or above by bootloaders like iPXE or kexec. GRUB behaves like the approach implemented here. Also fixes the documentation around pref_address and PHYSICAL_START to be accurate. [ dhansen: changelog tweak ] Co-developed-by: Cloud Hsu <cloudhsu@google.com> Signed-off-by: Cloud Hsu <cloudhsu@google.com> Signed-off-by: Chris Koch <chrisko@google.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: H. Peter Anvin (Intel) <hpa@zytor.com> Link: https://lore.kernel.org/all/20231215190521.3796022-1-chrisko%40google.com
Diffstat (limited to 'arch/x86/kernel/kexec-bzimage64.c')
-rw-r--r--arch/x86/kernel/kexec-bzimage64.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
index 2a422e00ed4b..cde167b0ea92 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -503,7 +503,10 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
kbuf.bufsz = kernel_len - kern16_size;
kbuf.memsz = PAGE_ALIGN(header->init_size);
kbuf.buf_align = header->kernel_alignment;
- kbuf.buf_min = MIN_KERNEL_LOAD_ADDR;
+ if (header->pref_address < MIN_KERNEL_LOAD_ADDR)
+ kbuf.buf_min = MIN_KERNEL_LOAD_ADDR;
+ else
+ kbuf.buf_min = header->pref_address;
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
ret = kexec_add_buffer(&kbuf);
if (ret)