From 2af446a69d493a747d991e860bd2615bc619fc09 Mon Sep 17 00:00:00 2001 From: yinchuang Date: Thu, 30 May 2024 09:12:40 +0800 Subject: [PATCH] [Sanitizer] Save ignore_reads_and_writes in JmpBuf Issue:I9T03H Signed-off-by: yinchuang --- .../sanitizer_common/sanitizer_libignore.cpp | 2 + .../lib/sanitizer_common/sanitizer_linux.cpp | 1 + .../lib/tsan/rtl/tsan_interceptors_posix.cpp | 2 + compiler-rt/lib/tsan/rtl/tsan_rtl.h | 2 + .../ohos_family_commands/ohos_common.py | 4 +- .../test/tsan/signal_handler_longjmp.cpp | 67 +++++++++++++++++++ 6 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 compiler-rt/test/tsan/signal_handler_longjmp.cpp diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp index 36294dbcc6ae..9f7cb5b16d44 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_libignore.cpp @@ -105,12 +105,14 @@ void LibIgnore::OnLibraryLoaded(const char *name) { lib->idx = idx; // OHOS_LOCAL #endif CHECK_LT(idx, ARRAY_SIZE(ignored_code_ranges_)); +#if SANITIZER_OHOS // OHOS_LOCAL VReport(1, "[Ignore] Adding ignore code range 0x%zx-0x%zx from library " "'%s' idx:0x%zx\n", ignored_code_ranges_[idx].begin, ignored_code_ranges_[idx].end, lib->name, lib->idx); +#endif ignored_code_ranges_[idx].begin = range.beg; ignored_code_ranges_[idx].end = range.end; atomic_store(&ignored_ranges_count_, idx + 1, memory_order_release); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 7d1315255005..30ac129f444f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_interface_internal.h" // OHOS_LOCAL +#include "sanitizer_platform_interceptors.h" // OHOS_LOCAL #include "sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 6b0e255f6db3..9e9449103cbf 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -515,6 +515,7 @@ static void SetJmp(ThreadState *thr, uptr sp) { JmpBuf *buf = thr->jmp_bufs.PushBack(); buf->sp = sp; buf->shadow_stack_pos = thr->shadow_stack_pos; + buf->ignore_reads_and_writes = thr->ignore_reads_and_writes; // OHOS_LOCAL ThreadSignalContext *sctx = SigCtx(thr); buf->int_signal_send = sctx ? sctx->int_signal_send : 0; buf->in_blocking_func = sctx ? @@ -540,6 +541,7 @@ static void LongJmp(ThreadState *thr, uptr *env) { atomic_store(&sctx->in_blocking_func, buf->in_blocking_func, memory_order_relaxed); } + thr->ignore_reads_and_writes = buf->ignore_reads_and_writes; // OHOS_LOCAL atomic_store(&thr->in_signal_handler, buf->in_signal_handler, memory_order_relaxed); JmpBufGarbageCollect(thr, buf->sp - 1); // do not collect buf->sp diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h index e1e121e2ee07..9eb1edc8ff06 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -96,6 +96,8 @@ struct ThreadSignalContext; struct JmpBuf { uptr sp; int int_signal_send; + // Todo: We need a suitable way to restore all relevant variables after longjmp to the state before setjmp. + int ignore_reads_and_writes; // OHOS_LOCAL bool in_blocking_func; uptr in_signal_handler; uptr *shadow_stack_pos; diff --git a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py index dbe446a68483..23a10f2e1109 100755 --- a/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py +++ b/compiler-rt/test/sanitizer_common/ohos_family_commands/ohos_common.py @@ -14,11 +14,11 @@ def host_to_device_path(path): def hdc_output(args): command = hdc_constants.get_hdc_cmd_prefix() + args + if verbose: + print ("[CMD]:" + " ".join(command)) return subprocess.check_output(command, stderr=subprocess.STDOUT, timeout=300) def hdc(args, attempts=1, check_stdout=''): - if verbose: - print (args) tmpname = tempfile.mktemp() out = open(tmpname, 'w') ret = 255 diff --git a/compiler-rt/test/tsan/signal_handler_longjmp.cpp b/compiler-rt/test/tsan/signal_handler_longjmp.cpp new file mode 100644 index 000000000000..f15c20b851b0 --- /dev/null +++ b/compiler-rt/test/tsan/signal_handler_longjmp.cpp @@ -0,0 +1,67 @@ +// RUN: rm -rf %t-dir +// RUN: mkdir %t-dir + +// RUN: %clangxx_tsan -O1 %s -DSHARED_LIB -fPIC -shared -fsanitize=thread %link_libcxx_tsan -o %t-dir/libtest.so +// RUN: %clangxx_tsan -O1 %s -fsanitize=thread %link_libcxx_tsan -o %t-dir/exe +// RUN: %run %t-dir/exe 2>&1 | FileCheck %s + +// REQUIRES: ohos_family + +#ifdef SHARED_LIB + +#include +#include +#include + +static int res = 1; +sigjmp_buf jump_buffer; + +void segv_handler(int) { siglongjmp(jump_buffer, 1); } + +int trigger_signal(void) { + struct sigaction segv_act{}, old_act{}; + segv_act.sa_handler = &segv_handler; + sigemptyset(&segv_act.sa_mask); + sigaction(SIGSEGV, &segv_act, &old_act); + + if (sigsetjmp(jump_buffer, 1) == 0) { + res = 2; + } + + sigaction(SIGSEGV, &old_act, NULL); + return res; +} + +struct Test { + Test() { + int res = trigger_signal(); + if (res == 2) { + fprintf(stderr, "Value is ok.\n"); + } else { + fprintf(stderr, "Value is not expected.\n"); + } + } +} test; + +#else + +#include +#include +#include + +int main(int argc, char **argv) { + std::string lib = std::string(dirname(argv[0])) + "/libtest.so"; + void *h = dlopen(lib.c_str(), RTLD_NOW); + if (h) { + dlclose(h); + } else { + fprintf(stderr, "dlopen failed of %s.\n", lib.c_str()); + } + + return 0; +} + +// CHECK-NOT: dlopen failed +// CHECK: Value is ok + +#endif \ No newline at end of file -- Gitee