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
8 changes: 6 additions & 2 deletions compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2412,7 +2412,11 @@ TSAN_INTERCEPTOR(int, vfork, int fake) {
}
#endif

#if SANITIZER_LINUX
#if SANITIZER_LINUX && !SANITIZER_ANDROID
// Bionic's pthread_create internally calls clone. When the CLONE_THREAD flag is
// set, clone does not create a new process but a new thread. This is a
// workaround for Android. Disabling the interception of clone solves the
// problem in most scenarios.
TSAN_INTERCEPTOR(int, clone, int (*fn)(void *), void *stack, int flags,
void *arg, int *parent_tid, void *tls, pid_t *child_tid) {
SCOPED_INTERCEPTOR_RAW(clone, fn, stack, flags, arg, parent_tid, tls,
Expand Down Expand Up @@ -3135,7 +3139,7 @@ void InitializeInterceptors() {

TSAN_INTERCEPT(fork);
TSAN_INTERCEPT(vfork);
#if SANITIZER_LINUX
#if SANITIZER_LINUX && !SANITIZER_ANDROID
TSAN_INTERCEPT(clone);
#endif
#if !SANITIZER_ANDROID
Expand Down
49 changes: 38 additions & 11 deletions compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,8 +486,20 @@ int ExtractRecvmsgFDs(void *msgp, int *fds, int nfd) {

// Reverse operation of libc stack pointer mangling
static uptr UnmangleLongJmpSp(uptr mangled_sp) {
#if defined(__x86_64__)
# if SANITIZER_LINUX
# if SANITIZER_ANDROID
if (longjmp_xor_key == 0) {
// bionic libc initialization process: __libc_init_globals ->
// __libc_init_vdso (calls strcmp) -> __libc_init_setjmp_cookie. strcmp is
// intercepted by TSan, so during TSan initialization the setjmp_cookie
// remains uninitialized. On Android, longjmp_xor_key must be set on first
// use.
InitializeLongjmpXorKey();
CHECK_NE(longjmp_xor_key, 0);
}
# endif

# if defined(__x86_64__)
# if SANITIZER_LINUX
// Reverse of:
// xor %fs:0x30, %rsi
// rol $0x11, %rsi
Expand Down Expand Up @@ -542,21 +554,31 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) {
# else
# define LONG_JMP_SP_ENV_SLOT 2
# endif
#elif SANITIZER_LINUX
# ifdef __aarch64__
# define LONG_JMP_SP_ENV_SLOT 13
# elif defined(__loongarch__)
# define LONG_JMP_SP_ENV_SLOT 1
# elif defined(__mips64)
# define LONG_JMP_SP_ENV_SLOT 1
# elif SANITIZER_ANDROID
# ifdef __aarch64__
# define LONG_JMP_SP_ENV_SLOT 3
# elif SANITIZER_RISCV64
# define LONG_JMP_SP_ENV_SLOT 3
# elif defined(__x86_64__)
# define LONG_JMP_SP_ENV_SLOT 6
# else
# error unsupported
# endif
# elif SANITIZER_LINUX
# ifdef __aarch64__
# define LONG_JMP_SP_ENV_SLOT 13
# elif defined(__loongarch__)
# define LONG_JMP_SP_ENV_SLOT 1
# elif defined(__mips64)
# define LONG_JMP_SP_ENV_SLOT 1
# elif SANITIZER_RISCV64
# define LONG_JMP_SP_ENV_SLOT 13
# elif defined(__s390x__)
# define LONG_JMP_SP_ENV_SLOT 9
# else
# define LONG_JMP_SP_ENV_SLOT 6
# endif
#endif
# endif

uptr ExtractLongJmpSp(uptr *env) {
uptr mangled_sp = env[LONG_JMP_SP_ENV_SLOT];
Expand Down Expand Up @@ -653,7 +675,12 @@ ThreadState *cur_thread() {
}
CHECK_EQ(0, internal_sigprocmask(SIG_SETMASK, &oldset, nullptr));
}
return thr;

// Skia calls mallopt(M_THREAD_DISABLE_MEM_INIT, 1), which sets the least
// significant bit of TLS_SLOT_SANITIZER to 1. Scudo allocator uses this bit
// as a flag to disable memory initialization. This is a workaround to get the
// correct ThreadState pointer.
reinterpret_cast<ThreadState*>(addr & ~1ULL);
}

void set_cur_thread(ThreadState *thr) {
Expand Down
6 changes: 5 additions & 1 deletion compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,14 @@ void ThreadStart(ThreadState *thr, Tid tid, ThreadID os_id,
}
#endif

#if !SANITIZER_GO
#if !SANITIZER_GO && !SANITIZER_ANDROID
// Don't imitate stack/TLS writes for the main thread,
// because its initialization is synchronized with all
// subsequent threads anyway.
// Because thr is created by MmapOrDie, the thr object
// is not in tls, the pointer to the thr object is in
// TLS_SLOT_SANITIZER slot. So skip this check on
// Android platform.
if (tid != kMainTid) {
if (stk_addr && stk_size) {
const uptr pc = StackTrace::GetNextInstructionPc(
Expand Down