Skip to content

Commit

Permalink
kexec: Allocate kernel above bzImage's pref_address
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Chris Koch authored and Dave Hansen committed Feb 22, 2024
1 parent ac456ca commit 43b1d3e
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 7 deletions.
3 changes: 2 additions & 1 deletion Documentation/arch/x86/boot.rst
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,8 @@ Protocol: 2.10+
address if possible.

A non-relocatable kernel will unconditionally move itself and to run
at this address.
at this address. A relocatable kernel will move itself to this address if it
loaded below this address.

============ =======
Field name: init_size
Expand Down
10 changes: 5 additions & 5 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2114,11 +2114,11 @@ config PHYSICAL_START
help
This gives the physical address where the kernel is loaded.

If kernel is a not relocatable (CONFIG_RELOCATABLE=n) then
bzImage will decompress itself to above physical address and
run from there. Otherwise, bzImage will run from the address where
it has been loaded by the boot loader and will ignore above physical
address.
If the kernel is not relocatable (CONFIG_RELOCATABLE=n) then bzImage
will decompress itself to above physical address and run from there.
Otherwise, bzImage will run from the address where it has been loaded
by the boot loader. The only exception is if it is loaded below the
above physical address, in which case it will relocate itself there.

In normal kdump cases one does not have to set/change this option
as now bzImage can be compiled as a completely relocatable image
Expand Down
5 changes: 4 additions & 1 deletion arch/x86/kernel/kexec-bzimage64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 43b1d3e

Please sign in to comment.