[libunwind] r363545 - [libunwind][AArch64] Fix libunwind::Registers_arm64::jumpto

Mikhail Maltsev via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 17 04:00:21 PDT 2019


Author: miyuki
Date: Mon Jun 17 04:00:21 2019
New Revision: 363545

URL: http://llvm.org/viewvc/llvm-project?rev=363545&view=rev
Log:
[libunwind][AArch64] Fix libunwind::Registers_arm64::jumpto

Summary:
The AArch64 version of the libunwind function which restores the
CPU state and resumes execution is not interrupt-safe. It restores
the target value of SP before loading the floating-point registers
from the context struct, but that struct is allocated on the stack
which is being deallocated. This means that if an interrupt occurs
during this function, and uses a lot of stack space, it could
overwrite the values about to be loaded into the floating-point
registers.

This patch fixes the issue.

Patch by Oliver Stannard.

Reviewers: phosek, chill

Reviewed By: chill

Subscribers: chill, javed.absar, kristof.beyls, christof, LukeCheeseman, pbarrio, olista01, libcxx-commits

Tags: #libc

Differential Revision: https://reviews.llvm.org/D63006

Modified:
    libunwind/trunk/src/UnwindRegistersRestore.S

Modified: libunwind/trunk/src/UnwindRegistersRestore.S
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindRegistersRestore.S?rev=363545&r1=363544&r2=363545&view=diff
==============================================================================
--- libunwind/trunk/src/UnwindRegistersRestore.S (original)
+++ libunwind/trunk/src/UnwindRegistersRestore.S Mon Jun 17 04:00:21 2019
@@ -575,7 +575,8 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind1
   ldp    x10,x11, [x0, #0x050]
   ldp    x12,x13, [x0, #0x060]
   ldp    x14,x15, [x0, #0x070]
-  ldp    x16,x17, [x0, #0x080]
+  // x16 and x17 were clobbered by the call into the unwinder, so no point in
+  // restoring them.
   ldp    x18,x19, [x0, #0x090]
   ldp    x20,x21, [x0, #0x0A0]
   ldp    x22,x23, [x0, #0x0B0]
@@ -583,8 +584,6 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind1
   ldp    x26,x27, [x0, #0x0D0]
   ldp    x28,x29, [x0, #0x0E0]
   ldr    x30,     [x0, #0x100]  // restore pc into lr
-  ldr    x1,      [x0, #0x0F8]
-  mov    sp,x1                  // restore sp
 
   ldp    d0, d1,  [x0, #0x110]
   ldp    d2, d3,  [x0, #0x120]
@@ -604,7 +603,13 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind1
   ldr    d30,     [x0, #0x200]
   ldr    d31,     [x0, #0x208]
 
+  // Finally, restore sp. This must be done after the the last read from the
+  // context struct, because it is allocated on the stack, and an exception
+  // could clobber the de-allocated portion of the stack after sp has been
+  // restored.
+  ldr    x16,     [x0, #0x0F8]
   ldp    x0, x1,  [x0, #0x000]  // restore x0,x1
+  mov    sp,x16                 // restore sp
   ret    x30                    // jump to pc
 
 #elif defined(__arm__) && !defined(__APPLE__)




More information about the cfe-commits mailing list