[PATCH] arm64: efi: Make runtime service wrapper more robust
Ard Biesheuvel
ardb at kernel.org
Mon Nov 28 01:49:39 PST 2022
Prevent abuse of the runtime service wrapper code by avoiding restoring
the shadow call stack pointer from the ordinary stack, or the stack
pointer itself from a GPR. Also, given that the exception recovery
routine is never called in an ordinary way, it doesn't need BTI landing
pads so it can be SYM_CODE rather than SYM_FUNC.
Cc: Sami Tolvanen <samitolvanen at google.com>
Cc: Kees Cook <keescook at chromium.org>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
arch/arm64/kernel/efi-rt-wrapper.S | 16 +++++++++-------
arch/arm64/kernel/efi.c | 6 +++++-
2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/kernel/efi-rt-wrapper.S b/arch/arm64/kernel/efi-rt-wrapper.S
index 67babd5f04c27c7a..afd3e81e1b627b87 100644
--- a/arch/arm64/kernel/efi-rt-wrapper.S
+++ b/arch/arm64/kernel/efi-rt-wrapper.S
@@ -28,7 +28,7 @@ SYM_FUNC_START(__efi_rt_asm_wrapper)
stp x27, x28, [sp, #96]
adr_this_cpu x8, __efi_rt_asm_recover_sp, x9
- str x29, [x8]
+ stp x29, x18, [x8]
/*
* We are lucky enough that no EFI runtime services take more than
@@ -56,15 +56,17 @@ SYM_FUNC_START(__efi_rt_asm_wrapper)
* called with preemption disabled and a separate shadow stack is used
* for interrupts.
*/
- mov x18, x2
+#ifdef CONFIG_SHADOW_CALL_STACK
+ ldr_this_cpu x18, __efi_rt_asm_recover_sp + 8, x9
+#endif
+
b efi_handle_corrupted_x18 // tail call
SYM_FUNC_END(__efi_rt_asm_wrapper)
-SYM_FUNC_START(__efi_rt_asm_recover)
- ldr_this_cpu x8, __efi_rt_asm_recover_sp, x9
- mov sp, x8
+SYM_CODE_START(__efi_rt_asm_recover)
+ mov sp, x30
- ldp x0, x18, [sp, #16]
+ ldr x0, [sp, #16]
ldp x19, x20, [sp, #32]
ldp x21, x22, [sp, #48]
ldp x23, x24, [sp, #64]
@@ -73,4 +75,4 @@ SYM_FUNC_START(__efi_rt_asm_recover)
ldp x29, x30, [sp], #112
b efi_handle_runtime_exception
-SYM_FUNC_END(__efi_rt_asm_recover)
+SYM_CODE_END(__efi_rt_asm_recover)
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 8d36e66a6e64cdaa..db7bdce1c7da578b 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -130,7 +130,7 @@ asmlinkage efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f)
return s;
}
-asmlinkage DEFINE_PER_CPU(u64, __efi_rt_asm_recover_sp);
+asmlinkage DEFINE_PER_CPU(u64[2], __efi_rt_asm_recover_sp);
asmlinkage efi_status_t __efi_rt_asm_recover(void);
@@ -151,6 +151,10 @@ bool efi_runtime_fixup_exception(struct pt_regs *regs, const char *msg)
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
dump_stack();
+ regs->regs[30] = __this_cpu_read(__efi_rt_asm_recover_sp[0]);
+#ifdef CONFIG_SHADOW_CALL_STACK
+ regs->regs[18] = __this_cpu_read(__efi_rt_asm_recover_sp[1]);
+#endif
regs->pc = (u64)__efi_rt_asm_recover;
return true;
}
--
2.35.1
More information about the linux-arm-kernel
mailing list