diff options
Diffstat (limited to 'compiler-rt/lib')
-rw-r--r-- | compiler-rt/lib/builtins/crtbegin.c | 46 | ||||
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerDriver.cpp | 1 | ||||
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerFlags.def | 1 | ||||
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerOptions.h | 1 | ||||
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp | 2 | ||||
-rw-r--r-- | compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp | 2 | ||||
-rw-r--r-- | compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp | 4 | ||||
-rw-r--r-- | compiler-rt/lib/scudo/standalone/secondary.h | 11 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_report.h | 13 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl.h | 3 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp | 6 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp | 77 |
12 files changed, 129 insertions, 38 deletions
diff --git a/compiler-rt/lib/builtins/crtbegin.c b/compiler-rt/lib/builtins/crtbegin.c index d5f7756..447474b 100644 --- a/compiler-rt/lib/builtins/crtbegin.c +++ b/compiler-rt/lib/builtins/crtbegin.c @@ -54,22 +54,33 @@ static void __attribute__((used)) __do_init(void) { } #ifdef CRT_HAS_INITFINI_ARRAY -#if __has_feature(ptrauth_init_fini) +# if __has_feature(ptrauth_init_fini) // TODO: use __ptrauth-qualified pointers when they are supported on clang side -#if __has_feature(ptrauth_init_fini_address_discrimination) +# if __has_feature(ptrauth_init_fini_address_discrimination) __attribute__((section(".init_array"), used)) static void *__init = ptrauth_sign_constant(&__do_init, ptrauth_key_init_fini_pointer, ptrauth_blend_discriminator( &__init, __ptrauth_init_fini_discriminator)); -#else +# else __attribute__((section(".init_array"), used)) static void *__init = ptrauth_sign_constant(&__do_init, ptrauth_key_init_fini_pointer, __ptrauth_init_fini_discriminator); -#endif -#else +# endif +# elif __has_feature(ptrauth_calls) +# ifdef __aarch64__ +// If ptrauth_init_fini feature is not present, compiler emits raw unsigned +// pointers in .init_array. Use inline assembly to avoid implicit signing of +// __do_init function pointer with ptrauth_calls enabled. +__asm__(".pushsection .init_array,\"aw\",@init_array\n\t" + ".xword __do_init\n\t" + ".popsection"); +# else +# error "ptrauth_calls is only supported for AArch64" +# endif +# else __attribute__((section(".init_array"), used)) static void (*__init)(void) = __do_init; -#endif +# endif #elif defined(__i386__) || defined(__x86_64__) __asm__(".pushsection .init,\"ax\",@progbits\n\t" "call __do_init\n\t" @@ -125,22 +136,33 @@ static void __attribute__((used)) __do_fini(void) { } #ifdef CRT_HAS_INITFINI_ARRAY -#if __has_feature(ptrauth_init_fini) +# if __has_feature(ptrauth_init_fini) // TODO: use __ptrauth-qualified pointers when they are supported on clang side -#if __has_feature(ptrauth_init_fini_address_discrimination) +# if __has_feature(ptrauth_init_fini_address_discrimination) __attribute__((section(".fini_array"), used)) static void *__fini = ptrauth_sign_constant(&__do_fini, ptrauth_key_init_fini_pointer, ptrauth_blend_discriminator( &__fini, __ptrauth_init_fini_discriminator)); -#else +# else __attribute__((section(".fini_array"), used)) static void *__fini = ptrauth_sign_constant(&__do_fini, ptrauth_key_init_fini_pointer, __ptrauth_init_fini_discriminator); -#endif -#else +# endif +# elif __has_feature(ptrauth_calls) +# ifdef __aarch64__ +// If ptrauth_init_fini feature is not present, compiler emits raw unsigned +// pointers in .fini_array. Use inline assembly to avoid implicit signing of +// __do_fini function pointer with ptrauth_calls enabled. +__asm__(".pushsection .fini_array,\"aw\",@fini_array\n\t" + ".xword __do_fini\n\t" + ".popsection"); +# else +# error "ptrauth_calls is only supported for AArch64" +# endif +# else __attribute__((section(".fini_array"), used)) static void (*__fini)(void) = __do_fini; -#endif +# endif #elif defined(__i386__) || defined(__x86_64__) __asm__(".pushsection .fini,\"ax\",@progbits\n\t" "call __do_fini\n\t" diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp index 40322e2..ad3a65a 100644 --- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp @@ -834,6 +834,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) { Options.HandleInt = Flags.handle_int; Options.HandleSegv = Flags.handle_segv; Options.HandleTerm = Flags.handle_term; + Options.HandleTrap = Flags.handle_trap; Options.HandleXfsz = Flags.handle_xfsz; Options.HandleUsr1 = Flags.handle_usr1; Options.HandleUsr2 = Flags.handle_usr2; diff --git a/compiler-rt/lib/fuzzer/FuzzerFlags.def b/compiler-rt/lib/fuzzer/FuzzerFlags.def index b88458a..96282b8 100644 --- a/compiler-rt/lib/fuzzer/FuzzerFlags.def +++ b/compiler-rt/lib/fuzzer/FuzzerFlags.def @@ -152,6 +152,7 @@ FUZZER_FLAG_INT(handle_ill, 1, "If 1, try to intercept SIGILL.") FUZZER_FLAG_INT(handle_fpe, 1, "If 1, try to intercept SIGFPE.") FUZZER_FLAG_INT(handle_int, 1, "If 1, try to intercept SIGINT.") FUZZER_FLAG_INT(handle_term, 1, "If 1, try to intercept SIGTERM.") +FUZZER_FLAG_INT(handle_trap, 1, "If 1, try to intercept SIGTRAP.") FUZZER_FLAG_INT(handle_xfsz, 1, "If 1, try to intercept SIGXFSZ.") FUZZER_FLAG_INT(handle_usr1, 1, "If 1, try to intercept SIGUSR1.") FUZZER_FLAG_INT(handle_usr2, 1, "If 1, try to intercept SIGUSR2.") diff --git a/compiler-rt/lib/fuzzer/FuzzerOptions.h b/compiler-rt/lib/fuzzer/FuzzerOptions.h index 72e2561..6478b63 100644 --- a/compiler-rt/lib/fuzzer/FuzzerOptions.h +++ b/compiler-rt/lib/fuzzer/FuzzerOptions.h @@ -82,6 +82,7 @@ struct FuzzingOptions { bool HandleInt = false; bool HandleSegv = false; bool HandleTerm = false; + bool HandleTrap = false; bool HandleXfsz = false; bool HandleUsr1 = false; bool HandleUsr2 = false; diff --git a/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp b/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp index 735d155..7f065c7 100644 --- a/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp @@ -410,7 +410,7 @@ void SetSignalHandler(const FuzzingOptions &Options) { // Early exit if no crash handler needed. if (!Options.HandleSegv && !Options.HandleBus && !Options.HandleIll && - !Options.HandleFpe && !Options.HandleAbrt) + !Options.HandleFpe && !Options.HandleAbrt && !Options.HandleTrap) return; // Set up the crash handler and wait until it is ready before proceeding. diff --git a/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp b/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp index 392c1e5..ae22ecf 100644 --- a/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp @@ -132,6 +132,8 @@ void SetSignalHandler(const FuzzingOptions& Options) { SetSigaction(SIGILL, CrashHandler); if (Options.HandleFpe) SetSigaction(SIGFPE, CrashHandler); + if (Options.HandleTrap) + SetSigaction(SIGTRAP, CrashHandler); if (Options.HandleXfsz) SetSigaction(SIGXFSZ, FileSizeExceedHandler); if (Options.HandleUsr1) diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp index 26a3b25..9b684e3 100644 --- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp @@ -752,8 +752,8 @@ TEST_F(RtsanOpenedFileTest, RewindDieWhenRealtime) { } #endif -TEST(TestRtsanInterceptors, IoctlDiesWhenRealtime) { - auto Func = []() { ioctl(0, FIONREAD); }; +TEST_F(RtsanOpenedFileTest, IoctlDiesWhenRealtime) { + auto Func = [this]() { ioctl(GetOpenFd(), FIONREAD); }; ExpectRealtimeDeath(Func, "ioctl"); ExpectNonRealtimeSurvival(Func); } diff --git a/compiler-rt/lib/scudo/standalone/secondary.h b/compiler-rt/lib/scudo/standalone/secondary.h index 286e5d3..f04c5b7 100644 --- a/compiler-rt/lib/scudo/standalone/secondary.h +++ b/compiler-rt/lib/scudo/standalone/secondary.h @@ -269,7 +269,8 @@ public: Entry.MemMap = MemMap; Entry.Time = UINT64_MAX; - if (useMemoryTagging<Config>(Options)) { + bool MemoryTaggingEnabled = useMemoryTagging<Config>(Options); + if (MemoryTaggingEnabled) { if (Interval == 0 && !SCUDO_FUCHSIA) { // Release the memory and make it inaccessible at the same time by // creating a new MAP_NOACCESS mapping on top of the existing mapping. @@ -302,7 +303,7 @@ public: if (Entry.Time != 0) Entry.Time = Time; - if (useMemoryTagging<Config>(Options) && QuarantinePos == -1U) { + if (MemoryTaggingEnabled && !useMemoryTagging<Config>(Options)) { // If we get here then memory tagging was disabled in between when we // read Options and when we locked Mutex. We can't insert our entry into // the quarantine or the cache because the permissions would be wrong so @@ -310,7 +311,8 @@ public: unmapCallBack(Entry.MemMap); break; } - if (Config::getQuarantineSize() && useMemoryTagging<Config>(Options)) { + + if (Config::getQuarantineSize()) { QuarantinePos = (QuarantinePos + 1) % Max(Config::getQuarantineSize(), 1u); if (!Quarantine[QuarantinePos].isValid()) { @@ -513,9 +515,10 @@ public: Quarantine[I].invalidate(); } } + QuarantinePos = -1U; + for (CachedBlock &Entry : LRUEntries) Entry.MemMap.setMemoryPermission(Entry.CommitBase, Entry.CommitSize, 0); - QuarantinePos = -1U; } void disable() NO_THREAD_SAFETY_ANALYSIS { Mutex.lock(); } diff --git a/compiler-rt/lib/tsan/rtl/tsan_report.h b/compiler-rt/lib/tsan/rtl/tsan_report.h index 8975540..53bb219 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_report.h +++ b/compiler-rt/lib/tsan/rtl/tsan_report.h @@ -12,6 +12,8 @@ #ifndef TSAN_REPORT_H #define TSAN_REPORT_H +#include "sanitizer_common/sanitizer_internal_defs.h" +#include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_symbolizer.h" #include "sanitizer_common/sanitizer_thread_registry.h" #include "sanitizer_common/sanitizer_vector.h" @@ -56,6 +58,7 @@ struct ReportMop { bool atomic; uptr external_tag; Vector<ReportMopMutex> mset; + StackTrace stack_trace; ReportStack *stack; ReportMop(); @@ -79,6 +82,7 @@ struct ReportLocation { int fd = 0; bool fd_closed = false; bool suppressable = false; + StackID stack_id = 0; ReportStack *stack = nullptr; }; @@ -89,15 +93,23 @@ struct ReportThread { ThreadType thread_type; char *name; Tid parent_tid; + StackID stack_id; ReportStack *stack; + bool suppressable; }; struct ReportMutex { int id; uptr addr; + StackID stack_id; ReportStack *stack; }; +struct AddedLocationAddr { + uptr addr; + usize locs_idx; +}; + class ReportDesc { public: ReportType typ; @@ -105,6 +117,7 @@ class ReportDesc { Vector<ReportStack*> stacks; Vector<ReportMop*> mops; Vector<ReportLocation*> locs; + Vector<AddedLocationAddr> added_location_addrs; Vector<ReportMutex*> mutexes; Vector<ReportThread*> threads; Vector<Tid> unique_tids; diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h index 46276f2..0b6d5f0 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -420,6 +420,7 @@ class ScopedReportBase { void AddSleep(StackID stack_id); void SetCount(int count); void SetSigNum(int sig); + void SymbolizeStackElems(void); const ReportDesc *GetReport() const; @@ -498,7 +499,7 @@ void ForkChildAfter(ThreadState *thr, uptr pc, bool start_thread); void ReportRace(ThreadState *thr, RawShadow *shadow_mem, Shadow cur, Shadow old, AccessType typ); -bool OutputReport(ThreadState *thr, const ScopedReport &srep); +bool OutputReport(ThreadState *thr, ScopedReport &srep); bool IsFiredSuppression(Context *ctx, ReportType type, StackTrace trace); bool IsExpectedReport(uptr addr, uptr size); diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp index 2a8aa19..2a2bf42 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp @@ -539,13 +539,15 @@ void ReportDeadlock(ThreadState *thr, uptr pc, DDReport *r) { for (int i = 0; i < r->n; i++) { for (int j = 0; j < (flags()->second_deadlock_stack ? 2 : 1); j++) { u32 stk = r->loop[i].stk[j]; + StackTrace stack; if (stk && stk != kInvalidStackID) { - rep.AddStack(StackDepotGet(stk), true); + stack = StackDepotGet(stk); } else { // Sometimes we fail to extract the stack trace (FIXME: investigate), // but we should still produce some stack trace in the report. - rep.AddStack(StackTrace(&dummy_pc, 1), true); + stack = StackTrace(&dummy_pc, 1); } + rep.AddStack(stack, true); } } OutputReport(thr, rep); diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp index 0820bf1..e6f0fda 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_internal_defs.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_stackdepot.h" @@ -187,10 +188,8 @@ void ScopedReportBase::AddMemoryAccess(uptr addr, uptr external_tag, Shadow s, mop->size = size; mop->write = !(typ & kAccessRead); mop->atomic = typ & kAccessAtomic; - mop->stack = SymbolizeStack(stack); mop->external_tag = external_tag; - if (mop->stack) - mop->stack->suppressable = true; + mop->stack_trace = stack; for (uptr i = 0; i < mset->Size(); i++) { MutexSet::Desc d = mset->Get(i); int id = this->AddMutex(d.addr, d.stack_id); @@ -199,6 +198,56 @@ void ScopedReportBase::AddMemoryAccess(uptr addr, uptr external_tag, Shadow s, } } +void ScopedReportBase::SymbolizeStackElems() { + // symbolize memory ops + for (usize i = 0, size = rep_->mops.Size(); i < size; i++) { + ReportMop *mop = rep_->mops[i]; + mop->stack = SymbolizeStack(mop->stack_trace); + if (mop->stack) + mop->stack->suppressable = true; + } + + // symbolize locations + for (usize i = 0, size = rep_->locs.Size(); i < size; i++) { + // added locations have a NULL placeholder - don't dereference them + if (ReportLocation *loc = rep_->locs[i]) + loc->stack = SymbolizeStackId(loc->stack_id); + } + + // symbolize any added locations + for (usize i = 0, size = rep_->added_location_addrs.Size(); i < size; i++) { + AddedLocationAddr *added_loc = &rep_->added_location_addrs[i]; + if (ReportLocation *loc = SymbolizeData(added_loc->addr)) { + loc->suppressable = true; + rep_->locs[added_loc->locs_idx] = loc; + } + } + + // Filter out any added location placeholders that could not be symbolized + usize j = 0; + for (usize i = 0, size = rep_->locs.Size(); i < size; i++) { + if (rep_->locs[i] != nullptr) { + rep_->locs[j] = rep_->locs[i]; + j++; + } + } + rep_->locs.Resize(j); + + // symbolize threads + for (usize i = 0, size = rep_->threads.Size(); i < size; i++) { + ReportThread *rt = rep_->threads[i]; + rt->stack = SymbolizeStackId(rt->stack_id); + if (rt->stack) + rt->stack->suppressable = rt->suppressable; + } + + // symbolize mutexes + for (usize i = 0, size = rep_->mutexes.Size(); i < size; i++) { + ReportMutex *rm = rep_->mutexes[i]; + rm->stack = SymbolizeStackId(rm->stack_id); + } +} + void ScopedReportBase::AddUniqueTid(Tid unique_tid) { rep_->unique_tids.PushBack(unique_tid); } @@ -216,10 +265,8 @@ void ScopedReportBase::AddThread(const ThreadContext *tctx, bool suppressable) { rt->name = internal_strdup(tctx->name); rt->parent_tid = tctx->parent_tid; rt->thread_type = tctx->thread_type; - rt->stack = 0; - rt->stack = SymbolizeStackId(tctx->creation_stack_id); - if (rt->stack) - rt->stack->suppressable = suppressable; + rt->stack_id = tctx->creation_stack_id; + rt->suppressable = suppressable; } #if !SANITIZER_GO @@ -270,7 +317,7 @@ int ScopedReportBase::AddMutex(uptr addr, StackID creation_stack_id) { rep_->mutexes.PushBack(rm); rm->id = rep_->mutexes.Size() - 1; rm->addr = addr; - rm->stack = SymbolizeStackId(creation_stack_id); + rm->stack_id = creation_stack_id; return rm->id; } @@ -288,7 +335,7 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) { loc->fd_closed = closed; loc->fd = fd; loc->tid = creat_tid; - loc->stack = SymbolizeStackId(creat_stack); + loc->stack_id = creat_stack; rep_->locs.PushBack(loc); AddThread(creat_tid); return; @@ -310,7 +357,7 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) { loc->heap_chunk_size = b->siz; loc->external_tag = b->tag; loc->tid = b->tid; - loc->stack = SymbolizeStackId(b->stk); + loc->stack_id = b->stk; rep_->locs.PushBack(loc); AddThread(b->tid); return; @@ -324,11 +371,8 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) { AddThread(tctx); } #endif - if (ReportLocation *loc = SymbolizeData(addr)) { - loc->suppressable = true; - rep_->locs.PushBack(loc); - return; - } + rep_->added_location_addrs.PushBack({addr, rep_->locs.Size()}); + rep_->locs.PushBack(nullptr); } #if !SANITIZER_GO @@ -628,11 +672,12 @@ static bool HandleRacyStacks(ThreadState *thr, VarSizeStackTrace traces[2]) { return false; } -bool OutputReport(ThreadState *thr, const ScopedReport &srep) { +bool OutputReport(ThreadState *thr, ScopedReport &srep) { // These should have been checked in ShouldReport. // It's too late to check them here, we have already taken locks. CHECK(flags()->report_bugs); CHECK(!thr->suppress_reports); + srep.SymbolizeStackElems(); atomic_store_relaxed(&ctx->last_symbolize_time_ns, NanoTime()); const ReportDesc *rep = srep.GetReport(); CHECK_EQ(thr->current_report, nullptr); |