diff options
Diffstat (limited to 'compiler-rt')
-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/test/fuzzer/SigTrapTest.cpp | 29 | ||||
-rw-r--r-- | compiler-rt/test/fuzzer/sig-trap.test | 11 | ||||
-rw-r--r-- | compiler-rt/test/rtsan/pthread_cond_wait.cpp | 48 |
11 files changed, 137 insertions, 19 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/test/fuzzer/SigTrapTest.cpp b/compiler-rt/test/fuzzer/SigTrapTest.cpp new file mode 100644 index 0000000..c3019a1 --- /dev/null +++ b/compiler-rt/test/fuzzer/SigTrapTest.cpp @@ -0,0 +1,29 @@ +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// Simple test for a fuzzer. The fuzzer must find the string "Hi!". +#include <assert.h> +#include <cstddef> +#include <cstdint> +#include <cstdlib> +#include <iostream> +#include <ostream> +#include <signal.h> + +static volatile int Sink; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + assert(Data); + if (Size > 0 && Data[0] == 'H') { + Sink = 1; + if (Size > 1 && Data[1] == 'i') { + Sink = 2; + if (Size > 2 && Data[2] == '!') { + std::cout << "BINGO; Found the target, exiting\n" << std::flush; + raise(SIGTRAP); + } + } + } + return 0; +} diff --git a/compiler-rt/test/fuzzer/sig-trap.test b/compiler-rt/test/fuzzer/sig-trap.test new file mode 100644 index 0000000..30d9d47 --- /dev/null +++ b/compiler-rt/test/fuzzer/sig-trap.test @@ -0,0 +1,11 @@ +# Check that libFuzzer handles SIGTRAP; disabled on Windows due to reliance on +# posix only features +UNSUPPORTED: target={{.*windows.*}} + +RUN: %cpp_compiler %S/SigTrapTest.cpp -o %t + +RUN: not %run %t 2>&1 | FileCheck %s +CHECK: BINGO +CHECK: ERROR: libFuzzer: deadly signal + +RUN: trap "%run %t -handle_trap=0" TRAP diff --git a/compiler-rt/test/rtsan/pthread_cond_wait.cpp b/compiler-rt/test/rtsan/pthread_cond_wait.cpp new file mode 100644 index 0000000..29afbf4b --- /dev/null +++ b/compiler-rt/test/rtsan/pthread_cond_wait.cpp @@ -0,0 +1,48 @@ +// RUN: %clangxx -fsanitize=realtime %s -o %t +// RUN: %run %t 2>&1 | FileCheck %s + +// UNSUPPORTED: ios + +// Intent: Ensures that pthread_cond_signal does not segfault under rtsan +// See issue #146120 + +#include <condition_variable> +#include <future> +#include <mutex> +#include <thread> + +#include <iostream> + +int main() { + std::cout << "Entry to main!" << std::endl; + + + // TODO: This is disabled because it does cause a test failure + /* + std::mutex mut; + std::condition_variable cv; + bool go{false}; + + const auto fut = std::async(std::launch::async, [&] { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + { + std::unique_lock<std::mutex> lock(mut); + go = true; + } + cv.notify_one(); + }); + + std::unique_lock<std::mutex> lock(mut); + // normal wait is fine + // cv.wait(lock, [&] { return go; }); + // but timed wait could segfault + + // NOTE: When a fix for the pthread_cond issue #146120 is fixed, uncomment this line + //cv.wait_for(lock, std::chrono::milliseconds(200), [&] { return go; }); + */ + + std::cout << "Exit from main!" << std::endl; +} + +// CHECK: Entry to main! +// CHECK-NEXT: Exit from main! |