diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2021-06-09 16:14:18 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-06-09 16:14:18 +0000 |
commit | eb5f5d8db6fcbda80ea3938627bcb1e8cc95666a (patch) | |
tree | cdd69b84cc2f793888992f8fb76440dc2db17c72 | |
parent | 381ed8f9d2d247a760d7348d928bef8ac534886c (diff) | |
parent | 9a1b7d124353afd76447ea2a9dea1903cc10b335 (diff) | |
download | bionic-eb5f5d8db6fcbda80ea3938627bcb1e8cc95666a.tar.gz |
Merge "Disable return PAC in __pthread_start." into sc-dev
-rw-r--r-- | libc/bionic/pthread_create.cpp | 5 | ||||
-rw-r--r-- | tests/stack_unwinding_test.cpp | 23 |
2 files changed, 24 insertions, 4 deletions
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp index 46d9e8672..121b26f82 100644 --- a/libc/bionic/pthread_create.cpp +++ b/libc/bionic/pthread_create.cpp @@ -331,6 +331,11 @@ void __set_stack_and_tls_vma_name(bool is_main_thread) { extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t); __attribute__((no_sanitize("hwaddress"))) +#ifdef __aarch64__ +// This function doesn't return, but it does appear in stack traces. Avoid using return PAC in this +// function because we may end up resetting IA, which may confuse unwinders due to mismatching keys. +__attribute__((target("branch-protection=bti"))) +#endif static int __pthread_start(void* arg) { pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(arg); diff --git a/tests/stack_unwinding_test.cpp b/tests/stack_unwinding_test.cpp index 0ff6f30a6..2f891a6e1 100644 --- a/tests/stack_unwinding_test.cpp +++ b/tests/stack_unwinding_test.cpp @@ -66,13 +66,28 @@ static int noinline unwind_one_frame_deeper() { return count; } -TEST(stack_unwinding, easy) { +static void UnwindTest() { int count = 0; _Unwind_Backtrace(FrameCounter, &count); int deeper_count = unwind_one_frame_deeper(); ASSERT_EQ(count + 1, deeper_count); } +TEST(stack_unwinding, easy) { + UnwindTest(); +} + +TEST(stack_unwinding, thread) { + pthread_t thread; + ASSERT_EQ(0, pthread_create(&thread, nullptr, [](void*) -> void* { + UnwindTest(); + return nullptr; + }, nullptr)); + void *retval; + ASSERT_EQ(0, pthread_join(thread, &retval)); + EXPECT_EQ(nullptr, retval); +} + struct UnwindData { volatile bool signal_handler_complete = false; int expected_frame_count = 0; @@ -98,7 +113,7 @@ static void verify_unwind_data(const UnwindData& unwind_data) { EXPECT_EQ(unwind_data.handler_frame_count + 1, unwind_data.handler_one_deeper_frame_count); } -static void noinline UnwindTest() { +static void noinline SignalUnwindTest() { g_unwind_data = {}; _Unwind_Backtrace(FrameCounter, &g_unwind_data.expected_frame_count); @@ -114,12 +129,12 @@ static void noinline UnwindTest() { TEST(stack_unwinding, unwind_through_signal_frame) { ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler); - UnwindTest(); + SignalUnwindTest(); } // On LP32, the SA_SIGINFO flag gets you __restore_rt instead of __restore. TEST(stack_unwinding, unwind_through_signal_frame_SA_SIGINFO) { ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler, SA_SIGINFO); - UnwindTest(); + SignalUnwindTest(); } |