Skip to content

Commit eb3d8ea

Browse files
mrutland-armwilldeacon
authored andcommitted
arm64: kexec: load from kimage prior to clobbering
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 <mark.rutland@arm.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: James Morse <james.morse@arm.com> Cc: Pasha Tatashin <pasha.tatashin@soleen.com> Cc: Will Deacon <will@kernel.org> Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com> Link: https://lore.kernel.org/r/20220516160735.731404-1-mark.rutland@arm.com Signed-off-by: Will Deacon <will@kernel.org>
1 parent 19bef63 commit eb3d8ea

1 file changed

Lines changed: 15 additions & 7 deletions

File tree

arch/arm64/kernel/relocate_kernel.S

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@
3737
* safe memory that has been set up to be preserved during the copy operation.
3838
*/
3939
SYM_CODE_START(arm64_relocate_new_kernel)
40+
/*
41+
* The kimage structure isn't allocated specially and may be clobbered
42+
* during relocation. We must load any values we need from it prior to
43+
* any relocation occurring.
44+
*/
45+
ldr x28, [x0, #KIMAGE_START]
46+
ldr x27, [x0, #KIMAGE_ARCH_EL2_VECTORS]
47+
ldr x26, [x0, #KIMAGE_ARCH_DTB_MEM]
48+
4049
/* Setup the list loop variables. */
4150
ldr x18, [x0, #KIMAGE_ARCH_ZERO_PAGE] /* x18 = zero page for BBM */
4251
ldr x17, [x0, #KIMAGE_ARCH_TTBR1] /* x17 = linear map copy */
@@ -72,21 +81,20 @@ SYM_CODE_START(arm64_relocate_new_kernel)
7281
ic iallu
7382
dsb nsh
7483
isb
75-
ldr x4, [x0, #KIMAGE_START] /* relocation start */
76-
ldr x1, [x0, #KIMAGE_ARCH_EL2_VECTORS] /* relocation start */
77-
ldr x0, [x0, #KIMAGE_ARCH_DTB_MEM] /* dtb address */
7884
turn_off_mmu x12, x13
7985

8086
/* Start new image. */
81-
cbz x1, .Lel1
82-
mov x1, x4 /* relocation start */
83-
mov x2, x0 /* dtb address */
87+
cbz x27, .Lel1
88+
mov x1, x28 /* kernel entry point */
89+
mov x2, x26 /* dtb address */
8490
mov x3, xzr
8591
mov x4, xzr
8692
mov x0, #HVC_SOFT_RESTART
8793
hvc #0 /* Jumps from el2 */
8894
.Lel1:
95+
mov x0, x26 /* dtb address */
96+
mov x1, xzr
8997
mov x2, xzr
9098
mov x3, xzr
91-
br x4 /* Jumps from el1 */
99+
br x28 /* Jumps from el1 */
92100
SYM_CODE_END(arm64_relocate_new_kernel)

0 commit comments

Comments
 (0)