diff options
author | Vitaly Buka <vitalybuka@google.com> | 2022-07-20 18:23:17 -0700 |
---|---|---|
committer | Vitaly Buka <vitalybuka@google.com> | 2022-07-22 13:40:16 -0700 |
commit | c93e4b6b2c497aecda82029d6f161bd81da26dab (patch) | |
tree | 70985b3ade5d0b0fad429a9b32150615111c69fd /compiler-rt | |
parent | 6a1ccf61cdf80c793f9c699ada33af5d85263b30 (diff) |
[asan] Reset stack bounds of context
ClearShadowMemoryForContextStack assumes that context contains the stack
bounds. This is not true for a context from getcontext or oucp of
swapcontext.
Reviewed By: kstoimenov
Differential Revision: https://reviews.llvm.org/D130218
Diffstat (limited to 'compiler-rt')
-rw-r--r-- | compiler-rt/lib/asan/asan_interceptors.cpp | 13 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_internal.h | 1 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_linux.cpp | 12 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_mac.cpp | 2 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_win.cpp | 2 | ||||
-rw-r--r-- | compiler-rt/test/asan/TestCases/Linux/swapcontext_test.cpp | 6 |
6 files changed, 34 insertions, 2 deletions
diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp index 78d23abaad63..ff6ffeca36d5 100644 --- a/compiler-rt/lib/asan/asan_interceptors.cpp +++ b/compiler-rt/lib/asan/asan_interceptors.cpp @@ -253,6 +253,14 @@ static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) { PoisonShadow(bottom, ssize, 0); } +INTERCEPTOR(int, getcontext, struct ucontext_t *ucp) { + // API does not requires to have ucp clean, and sets only part of fields. We + // use ucp->uc_stack to unpoison new stack. We prefer to have zeroes then + // uninitialized bytes. + ResetContextStack(ucp); + return REAL(getcontext)(ucp); +} + INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp, struct ucontext_t *ucp) { static bool reported_warning = false; @@ -266,6 +274,10 @@ INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp, uptr stack, ssize; ReadContextStack(ucp, &stack, &ssize); ClearShadowMemoryForContextStack(stack, ssize); + + // See getcontext interceptor. + ResetContextStack(oucp); + # if __has_attribute(__indirect_return__) && \ (defined(__x86_64__) || defined(__i386__)) int (*real_swapcontext)(struct ucontext_t *, struct ucontext_t *) @@ -643,6 +655,7 @@ void InitializeAsanInterceptors() { ASAN_INTERCEPT_FUNC(longjmp); #if ASAN_INTERCEPT_SWAPCONTEXT + ASAN_INTERCEPT_FUNC(getcontext); ASAN_INTERCEPT_FUNC(swapcontext); #endif #if ASAN_INTERCEPT__LONGJMP diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h index 7468f126d37b..9c46f225116e 100644 --- a/compiler-rt/lib/asan/asan_internal.h +++ b/compiler-rt/lib/asan/asan_internal.h @@ -106,6 +106,7 @@ void AsanApplyToGlobals(globals_op_fptr op, const void *needle); void AsanOnDeadlySignal(int, void *siginfo, void *context); void ReadContextStack(void *context, uptr *stack, uptr *ssize); +void ResetContextStack(void *context); void StopInitOrderChecking(); // Wrapper for TLS/TSD. diff --git a/compiler-rt/lib/asan/asan_linux.cpp b/compiler-rt/lib/asan/asan_linux.cpp index defd81bc19e2..89450fc120a0 100644 --- a/compiler-rt/lib/asan/asan_linux.cpp +++ b/compiler-rt/lib/asan/asan_linux.cpp @@ -214,11 +214,19 @@ void ReadContextStack(void *context, uptr *stack, uptr *ssize) { *stack = (uptr)ucp->uc_stack.ss_sp; *ssize = ucp->uc_stack.ss_size; } -#else + +void ResetContextStack(void *context) { + ucontext_t *ucp = (ucontext_t *)context; + ucp->uc_stack.ss_sp = nullptr; + ucp->uc_stack.ss_size = 0; +} +# else void ReadContextStack(void *context, uptr *stack, uptr *ssize) { UNIMPLEMENTED(); } -#endif + +void ResetContextStack(void *context) { UNIMPLEMENTED(); } +# endif void *AsanDlSymNext(const char *sym) { return dlsym(RTLD_NEXT, sym); diff --git a/compiler-rt/lib/asan/asan_mac.cpp b/compiler-rt/lib/asan/asan_mac.cpp index 4f4ce92cc6a1..a2d5c31a3f77 100644 --- a/compiler-rt/lib/asan/asan_mac.cpp +++ b/compiler-rt/lib/asan/asan_mac.cpp @@ -99,6 +99,8 @@ void ReadContextStack(void *context, uptr *stack, uptr *ssize) { UNIMPLEMENTED(); } +void ResetContextStack(void *context) { UNIMPLEMENTED(); } + // Support for the following functions from libdispatch on Mac OS: // dispatch_async_f() // dispatch_async() diff --git a/compiler-rt/lib/asan/asan_win.cpp b/compiler-rt/lib/asan/asan_win.cpp index 81958038fb1c..f11df0613d1f 100644 --- a/compiler-rt/lib/asan/asan_win.cpp +++ b/compiler-rt/lib/asan/asan_win.cpp @@ -267,6 +267,8 @@ void ReadContextStack(void *context, uptr *stack, uptr *ssize) { UNIMPLEMENTED(); } +void ResetContextStack(void *context) { UNIMPLEMENTED(); } + void AsanOnDeadlySignal(int, void *siginfo, void *context) { UNIMPLEMENTED(); } bool PlatformUnpoisonStacks() { return false; } diff --git a/compiler-rt/test/asan/TestCases/Linux/swapcontext_test.cpp b/compiler-rt/test/asan/TestCases/Linux/swapcontext_test.cpp index 7478225899af..102e62f5d4e8 100644 --- a/compiler-rt/test/asan/TestCases/Linux/swapcontext_test.cpp +++ b/compiler-rt/test/asan/TestCases/Linux/swapcontext_test.cpp @@ -9,6 +9,8 @@ // Android and musl do not support swapcontext. // REQUIRES: x86-target-arch && glibc-2.27 +#include <assert.h> +#include <memory.h> #include <stdio.h> #include <ucontext.h> #include <unistd.h> @@ -33,6 +35,7 @@ void ThrowAndCatch() { } void Child(int mode) { + assert(orig_context.uc_stack.ss_size == 0); char x[32] = {0}; // Stack gets poisoned. printf("Child: %p\n", x); ThrowAndCatch(); // Simulate __asan_handle_no_return(). @@ -50,13 +53,16 @@ void Child(int mode) { int Run(int arg, int mode, char *child_stack) { printf("Child stack: %p\n", child_stack); // Setup child context. + memset(&child_context, 0xff, sizeof(child_context)); getcontext(&child_context); + assert(child_context.uc_stack.ss_size == 0); child_context.uc_stack.ss_sp = child_stack; child_context.uc_stack.ss_size = kStackSize / 2; if (mode == 0) { child_context.uc_link = &orig_context; } makecontext(&child_context, (void (*)())Child, 1, mode); + memset(&orig_context, 0xff, sizeof(orig_context)); if (swapcontext(&orig_context, &child_context) < 0) { perror("swapcontext"); return 0; |