Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions compiler-rt/include/sanitizer/asan_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,13 @@ void SANITIZER_CDECL __asan_handle_no_return(void);
/// trace. Returns 1 if successful, 0 if not.
int SANITIZER_CDECL __asan_update_allocation_context(void *addr);

/// Disables fake stack for the current thread.
/// Temporarily disables use-after-return detection for current thread.
void SANITIZER_CDECL __asan_disable_fake_stack(void);

/// (Re)enables fake stack for the current thread.
void SANITIZER_CDECL __asan_enable_fake_stack(void);

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
21 changes: 20 additions & 1 deletion compiler-rt/lib/asan/asan_fake_stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,23 @@ static void SetTLSFakeStack(FakeStack*) {}
void ResetTLSFakeStack() {}
#endif // (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_FUCHSIA

static void DisableFakeStack() {
AsanThread* t = GetCurrentThread();
if (t) {
t->SetFakeStackEnabled(false);
}
}

static void EnableFakeStack() {
AsanThread* t = GetCurrentThread();
if (t) {
t->SetFakeStackEnabled(true);
}
}

static FakeStack* GetFakeStack() {
AsanThread* t = GetCurrentThread();
if (!t)
if (!t || !t->IsFakeStackEnabled())
return nullptr;
return t->get_or_create_fake_stack();
}
Expand Down Expand Up @@ -362,4 +376,9 @@ void __asan_allocas_unpoison(uptr top, uptr bottom) {
REAL(memset)(reinterpret_cast<void*>(MemToShadow(top)), 0,
(bottom - top) / ASAN_SHADOW_GRANULARITY);
}

SANITIZER_INTERFACE_ATTRIBUTE
void __asan_disable_fake_stack() { return DisableFakeStack(); }
SANITIZER_INTERFACE_ATTRIBUTE
void __asan_enable_fake_stack() { return EnableFakeStack(); }
} // extern "C"
2 changes: 2 additions & 0 deletions compiler-rt/lib/asan/asan_interface.inc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ INTERFACE_FUNCTION(__asan_alloca_poison)
INTERFACE_FUNCTION(__asan_allocas_unpoison)
INTERFACE_FUNCTION(__asan_before_dynamic_init)
INTERFACE_FUNCTION(__asan_describe_address)
INTERFACE_FUNCTION(__asan_disable_fake_stack)
INTERFACE_FUNCTION(__asan_enable_fake_stack)
INTERFACE_FUNCTION(__asan_exp_load1)
INTERFACE_FUNCTION(__asan_exp_load2)
INTERFACE_FUNCTION(__asan_exp_load4)
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/lib/asan/asan_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() {
void AsanThread::Init(const InitOptions *options) {
DCHECK_NE(tid(), kInvalidTid);
next_stack_top_ = next_stack_bottom_ = 0;
fake_stack_enabled_ = true;
atomic_store(&stack_switching_, false, memory_order_release);
CHECK_EQ(this->stack_size(), 0U);
SetThreadStackAndTls(options);
Expand Down
7 changes: 7 additions & 0 deletions compiler-rt/lib/asan/asan_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ class AsanThread {
GetStartData(&data, sizeof(data));
}

bool IsFakeStackEnabled() const { return fake_stack_enabled_; }
void SetFakeStackEnabled(bool enabled) {
fake_stack_enabled_ = enabled;
ResetTLSFakeStack();
}

private:
// NOTE: There is no AsanThread constructor. It is allocated
// via mmap() and *must* be valid in zero-initialized state.
Expand Down Expand Up @@ -179,6 +185,7 @@ class AsanThread {
DTLS *dtls_;

FakeStack *fake_stack_;
bool fake_stack_enabled_;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please make it a counter

AsanThreadLocalMallocStorage malloc_storage_;
AsanStats stats_;
bool unwinding_;
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/lib/asan_abi/asan_abi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ void *__asan_abi_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
void **end) {
return NULL;
}
void __asan_abi_disable_fake_stack(void) {}
void __asan_abi_enable_fake_stack(void) {}

// Functions concerning poisoning and unpoisoning fake stack alloca
void __asan_abi_alloca_poison(void *addr, size_t size) {}
Expand Down
3 changes: 3 additions & 0 deletions compiler-rt/lib/asan_abi/asan_abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ void *__asan_abi_load_cxx_array_cookie(void **p);
void *__asan_abi_get_current_fake_stack();
void *__asan_abi_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
void **end);
void *__asan_abi_disable_fake_stack();
void *__asan_abi_enable_fake_stack();

// Functions concerning poisoning and unpoisoning fake stack alloca
void __asan_abi_alloca_poison(void *addr, size_t size);
void __asan_abi_allocas_unpoison(void *top, void *bottom);
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/lib/asan_abi/asan_abi_shim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
void **end) {
return __asan_abi_addr_is_in_fake_stack(fake_stack, addr, beg, end);
}
void __asan_disable_fake_stack(void) { return __asan_abi_disable_fake_stack(); }
void __asan_enable_fake_stack(void) { return __asan_abi_enable_fake_stack(); }

// Functions concerning poisoning and unpoisoning fake stack alloca
void __asan_alloca_poison(uptr addr, uptr size) {
Expand Down
32 changes: 32 additions & 0 deletions compiler-rt/test/asan/TestCases/disable_fake_stack.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// RUN: %clangxx_asan %s -o %t && %run %t

#include "defines.h"

#include <cassert>
#include <sanitizer/asan_interface.h>

volatile uintptr_t saved;

ATTRIBUTE_NOINLINE bool IsOnRealStack(uintptr_t caller_frame) {
uintptr_t this_frame =
reinterpret_cast<uintptr_t>(__builtin_frame_address(0));
return this_frame <= saved && saved <= caller_frame;
}

ATTRIBUTE_NOINLINE bool IsOnStack() {
volatile char temp = ' ';
saved = reinterpret_cast<uintptr_t>(&temp);
return IsOnRealStack(reinterpret_cast<uintptr_t>(__builtin_frame_address(0)));
}

int main(int argc, char *argv[]) {
assert(!IsOnStack());

__asan_disable_fake_stack();
assert(IsOnStack());

__asan_enable_fake_stack();
assert(!IsOnStack());

return 0;
}
Loading