Skip to content

Commit

Permalink
arm64: kexec: load from kimage prior to clobbering
Browse files Browse the repository at this point in the history
In arm64_relocate_new_kernel() we load some fields out of the kimage
structure after relocation has occurred. As the kimage structure isn't
allocated to be relocation-safe, it may be clobbered during relocation,
and we may load junk values out of the structure.

Due to this, kexec may fail when the kimage allocation happens to fall
within a PA range that an object will be relocated to. This has been
observed to occur for regular kexec on a QEMU TCG 'virt' machine with
2GiB of RAM, where the PA range of the new kernel image overlaps the
kimage structure.

Avoid this by ensuring we load all values from the kimage structure
prior to relocation.

I've tested this atop v5.16 and v5.18-rc6.

Fixes: 878fdbd ("arm64: kexec: pass kimage as the only argument to relocation function")
Signed-off-by: Mark Rutland <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: James Morse <[email protected]>
Cc: Pasha Tatashin <[email protected]>
Cc: Will Deacon <[email protected]>
Reviewed-by: Pasha Tatashin <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Will Deacon <[email protected]>
  • Loading branch information
Mark Rutland authored and willdeacon committed May 17, 2022
1 parent 19bef63 commit eb3d8ea
Showing 1 changed file with 15 additions and 7 deletions.
22 changes: 15 additions & 7 deletions arch/arm64/kernel/relocate_kernel.S
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@
* safe memory that has been set up to be preserved during the copy operation.
*/
SYM_CODE_START(arm64_relocate_new_kernel)
/*
* The kimage structure isn't allocated specially and may be clobbered
* during relocation. We must load any values we need from it prior to
* any relocation occurring.
*/
ldr x28, [x0, #KIMAGE_START]
ldr x27, [x0, #KIMAGE_ARCH_EL2_VECTORS]
ldr x26, [x0, #KIMAGE_ARCH_DTB_MEM]

/* Setup the list loop variables. */
ldr x18, [x0, #KIMAGE_ARCH_ZERO_PAGE] /* x18 = zero page for BBM */
ldr x17, [x0, #KIMAGE_ARCH_TTBR1] /* x17 = linear map copy */
Expand Down Expand Up @@ -72,21 +81,20 @@ SYM_CODE_START(arm64_relocate_new_kernel)
ic iallu
dsb nsh
isb
ldr x4, [x0, #KIMAGE_START] /* relocation start */
ldr x1, [x0, #KIMAGE_ARCH_EL2_VECTORS] /* relocation start */
ldr x0, [x0, #KIMAGE_ARCH_DTB_MEM] /* dtb address */
turn_off_mmu x12, x13

/* Start new image. */
cbz x1, .Lel1
mov x1, x4 /* relocation start */
mov x2, x0 /* dtb address */
cbz x27, .Lel1
mov x1, x28 /* kernel entry point */
mov x2, x26 /* dtb address */
mov x3, xzr
mov x4, xzr
mov x0, #HVC_SOFT_RESTART
hvc #0 /* Jumps from el2 */
.Lel1:
mov x0, x26 /* dtb address */
mov x1, xzr
mov x2, xzr
mov x3, xzr
br x4 /* Jumps from el1 */
br x28 /* Jumps from el1 */
SYM_CODE_END(arm64_relocate_new_kernel)

0 comments on commit eb3d8ea

Please sign in to comment.