From e55d896eae63e3eeeb11705c97f011e9a7a47da9 Mon Sep 17 00:00:00 2001 From: David Trevelyan Date: Sat, 1 Jun 2024 17:20:20 +0100 Subject: [PATCH 01/47] Clean out temp files in test fixture SetUp too --- .../lib/radsan/tests/radsan_test_interceptors.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp index 20de4e73a78c6..316c294ba8294 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp @@ -45,18 +45,20 @@ class RadsanFileTest : public ::testing::Test { void SetUp() override { const ::testing::TestInfo *const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - file_path = std::string("/tmp/radsan_temporary_test_file_") + - test_info->name() + ".txt"; + file_path_ = std::string("/tmp/radsan_temporary_test_file_") + + test_info->name() + ".txt"; + RemoveTemporaryFile(); } - // Gets a file path with the test's name in in + // Gets a file path with the test's name in it // This file will be removed if it exists at the end of the test - const char *GetTemporaryFilePath() const { return file_path.c_str(); } + const char *GetTemporaryFilePath() const { return file_path_.c_str(); } - void TearDown() override { std::remove(GetTemporaryFilePath()); } + void TearDown() override { RemoveTemporaryFile(); } private: - std::string file_path; + void RemoveTemporaryFile() const { std::remove(GetTemporaryFilePath()); } + std::string file_path_; }; /* From a4fc510fcb481696d01d2489219705112fab202a Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Tue, 7 May 2024 15:36:27 -0700 Subject: [PATCH 02/47] One round of renaming --- compiler-rt/lib/radsan/radsan.cpp | 8 +- compiler-rt/lib/radsan/radsan_context.cpp | 50 +++++----- compiler-rt/lib/radsan/radsan_context.h | 20 ++-- .../lib/radsan/radsan_interceptors.cpp | 99 +++++++++---------- .../lib/radsan/tests/radsan_test_context.cpp | 60 +++++------ 5 files changed, 117 insertions(+), 120 deletions(-) diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp index bd3295e547aa7..273c81fafa549 100644 --- a/compiler-rt/lib/radsan/radsan.cpp +++ b/compiler-rt/lib/radsan/radsan.cpp @@ -15,18 +15,18 @@ extern "C" { RADSAN_EXPORT void radsan_init() { radsan::initialiseInterceptors(); } RADSAN_EXPORT void radsan_realtime_enter() { - radsan::getContextForThisThread().realtimePush(); + radsan::getContextForThisThread().RealtimePush(); } RADSAN_EXPORT void radsan_realtime_exit() { - radsan::getContextForThisThread().realtimePop(); + radsan::getContextForThisThread().RealtimePop(); } RADSAN_EXPORT void radsan_off() { - radsan::getContextForThisThread().bypassPush(); + radsan::getContextForThisThread().BypassPush(); } RADSAN_EXPORT void radsan_on() { - radsan::getContextForThisThread().bypassPop(); + radsan::getContextForThisThread().BypassPop(); } } diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp index 4ec216e219c7d..c84d64ee678fa 100644 --- a/compiler-rt/lib/radsan/radsan_context.cpp +++ b/compiler-rt/lib/radsan/radsan_context.cpp @@ -22,9 +22,9 @@ using namespace __sanitizer; namespace detail { -static pthread_key_t key; -static pthread_once_t key_once = PTHREAD_ONCE_INIT; -void internalFree(void *ptr) { InternalFree(ptr); } +static pthread_key_t Key; +static pthread_once_t KeyOnce = PTHREAD_ONCE_INIT; +void internalFree(void *Ptr) { __sanitizer::InternalFree(Ptr); } } // namespace detail @@ -32,49 +32,49 @@ namespace radsan { Context::Context() = default; -void Context::realtimePush() { realtime_depth_++; } +void Context::RealtimePush() { RealtimeDepth++; } -void Context::realtimePop() { realtime_depth_--; } +void Context::RealtimePop() { RealtimeDepth--; } -void Context::bypassPush() { bypass_depth_++; } +void Context::BypassPush() { BypassDepth++; } -void Context::bypassPop() { bypass_depth_--; } +void Context::BypassPop() { BypassDepth--; } -void Context::expectNotRealtime(const char *intercepted_function_name) { - if (inRealtimeContext() && !isBypassed()) { - bypassPush(); - printDiagnostics(intercepted_function_name); +void Context::ExpectNotRealtime(const char *InterceptedFunctionName) { + if (InRealtimeContext() && !IsBypassed()) { + BypassPush(); + PrintDiagnostics(InterceptedFunctionName); exit(EXIT_FAILURE); - bypassPop(); + BypassPop(); } } -bool Context::inRealtimeContext() const { return realtime_depth_ > 0; } +bool Context::InRealtimeContext() const { return RealtimeDepth > 0; } -bool Context::isBypassed() const { return bypass_depth_ > 0; } +bool Context::IsBypassed() const { return BypassDepth > 0; } -void Context::printDiagnostics(const char *intercepted_function_name) { +void Context::PrintDiagnostics(const char *InterceptedFunctionName) { fprintf(stderr, "Real-time violation: intercepted call to real-time unsafe function " "`%s` in real-time context! Stack trace:\n", - intercepted_function_name); + InterceptedFunctionName); radsan::printStackTrace(); } Context &getContextForThisThread() { - auto make_tls_key = []() { - CHECK_EQ(pthread_key_create(&detail::key, detail::internalFree), 0); + auto MakeTlsKey = []() { + CHECK_EQ(pthread_key_create(&detail::Key, detail::internalFree), 0); }; - pthread_once(&detail::key_once, make_tls_key); - auto *ptr = static_cast(pthread_getspecific(detail::key)); - if (ptr == nullptr) { - ptr = static_cast(InternalAlloc(sizeof(Context))); - new(ptr) Context(); - pthread_setspecific(detail::key, ptr); + pthread_once(&detail::KeyOnce, MakeTlsKey); + Context *CurrentThreadContext = static_cast(pthread_getspecific(detail::Key)); + if (CurrentThreadContext == nullptr) { + CurrentThreadContext = static_cast(InternalAlloc(sizeof(Context))); + new(CurrentThreadContext) Context(); + pthread_setspecific(detail::Key, CurrentThreadContext); } - return *ptr; + return *CurrentThreadContext; } } // namespace radsan diff --git a/compiler-rt/lib/radsan/radsan_context.h b/compiler-rt/lib/radsan/radsan_context.h index 66d810ce97735..fd522a5974e5f 100644 --- a/compiler-rt/lib/radsan/radsan_context.h +++ b/compiler-rt/lib/radsan/radsan_context.h @@ -14,21 +14,21 @@ class Context { public: Context(); - void realtimePush(); - void realtimePop(); + void RealtimePush(); + void RealtimePop(); - void bypassPush(); - void bypassPop(); + void BypassPush(); + void BypassPop(); - void expectNotRealtime(const char *interpreted_function_name); + void ExpectNotRealtime(const char *interpreted_function_name); private: - bool inRealtimeContext() const; - bool isBypassed() const; - void printDiagnostics(const char *intercepted_function_name); + bool InRealtimeContext() const; + bool IsBypassed() const; + void PrintDiagnostics(const char *InterceptedFunctionName); - int realtime_depth_{0}; - int bypass_depth_{0}; + int RealtimeDepth{0}; + int BypassDepth{0}; }; Context &getContextForThisThread(); diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp index 2ff174d5118fc..4e06d20cbdcbf 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.cpp +++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp @@ -38,8 +38,8 @@ using namespace __sanitizer; namespace radsan { -void expectNotRealtime(const char *intercepted_function_name) { - getContextForThisThread().expectNotRealtime(intercepted_function_name); +void ExpectNotRealtime(const char *InterceptedFunctionName) { + getContextForThisThread().ExpectNotRealtime(InterceptedFunctionName); } } // namespace radsan @@ -50,8 +50,7 @@ void expectNotRealtime(const char *intercepted_function_name) { INTERCEPTOR(int, open, const char *path, int oflag, ...) { // TODO Establish whether we should intercept here if the flag contains // O_NONBLOCK - radsan::expectNotRealtime("open"); - + radsan::ExpectNotRealtime("open"); va_list args; va_start(args, oflag); const mode_t mode = va_arg(args, int); @@ -64,8 +63,7 @@ INTERCEPTOR(int, open, const char *path, int oflag, ...) { INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) { // TODO Establish whether we should intercept here if the flag contains // O_NONBLOCK - radsan::expectNotRealtime("openat"); - + radsan::ExpectNotRealtime("openat"); va_list args; va_start(args, oflag); mode_t mode = va_arg(args, int); @@ -78,14 +76,13 @@ INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) { INTERCEPTOR(int, creat, const char *path, mode_t mode) { // TODO Establish whether we should intercept here if the flag contains // O_NONBLOCK - radsan::expectNotRealtime("creat"); + radsan::ExpectNotRealtime("creat"); auto result = REAL(creat)(path, mode); return result; } INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) { - radsan::expectNotRealtime("fcntl"); - + radsan::ExpectNotRealtime("fcntl"); va_list args; va_start(args, cmd); @@ -105,34 +102,34 @@ INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) { } INTERCEPTOR(int, close, int filedes) { - radsan::expectNotRealtime("close"); + radsan::ExpectNotRealtime("close"); return REAL(close)(filedes); } INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) { - radsan::expectNotRealtime("fopen"); + radsan::ExpectNotRealtime("fopen"); return REAL(fopen)(path, mode); } INTERCEPTOR(size_t, fread, void *ptr, size_t size, size_t nitems, FILE *stream) { - radsan::expectNotRealtime("fread"); + radsan::ExpectNotRealtime("fread"); return REAL(fread)(ptr, size, nitems, stream); } INTERCEPTOR(size_t, fwrite, const void *ptr, size_t size, size_t nitems, FILE *stream) { - radsan::expectNotRealtime("fwrite"); + radsan::ExpectNotRealtime("fwrite"); return REAL(fwrite)(ptr, size, nitems, stream); } INTERCEPTOR(int, fclose, FILE *stream) { - radsan::expectNotRealtime("fclose"); + radsan::ExpectNotRealtime("fclose"); return REAL(fclose)(stream); } INTERCEPTOR(int, fputs, const char *s, FILE *stream) { - radsan::expectNotRealtime("fputs"); + radsan::ExpectNotRealtime("fputs"); return REAL(fputs)(s, stream); } @@ -141,7 +138,7 @@ INTERCEPTOR(int, fputs, const char *s, FILE *stream) { */ INTERCEPTOR(int, puts, const char *s) { - radsan::expectNotRealtime("puts"); + radsan::ExpectNotRealtime("puts"); return REAL(puts)(s); } @@ -154,77 +151,77 @@ INTERCEPTOR(int, puts, const char *s) { // OSSpinLockLock is deprecated, but still in use in libc++ #pragma clang diagnostic ignored "-Wdeprecated-declarations" INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) { - radsan::expectNotRealtime("OSSpinLockLock"); + radsan::ExpectNotRealtime("OSSpinLockLock"); return REAL(OSSpinLockLock)(lock); } #pragma clang diagnostic pop INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) { - radsan::expectNotRealtime("os_unfair_lock_lock"); + radsan::ExpectNotRealtime("os_unfair_lock_lock"); return REAL(os_unfair_lock_lock)(lock); } #elif SANITIZER_LINUX INTERCEPTOR(int, pthread_spin_lock, pthread_spinlock_t *spinlock) { - radsan::expectNotRealtime("pthread_spin_lock"); + radsan::ExpectNotRealtime("pthread_spin_lock"); return REAL(pthread_spin_lock)(spinlock); } #endif INTERCEPTOR(int, pthread_create, pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { - radsan::expectNotRealtime("pthread_create"); + radsan::ExpectNotRealtime("pthread_create"); return REAL(pthread_create)(thread, attr, start_routine, arg); } INTERCEPTOR(int, pthread_mutex_lock, pthread_mutex_t *mutex) { - radsan::expectNotRealtime("pthread_mutex_lock"); + radsan::ExpectNotRealtime("pthread_mutex_lock"); return REAL(pthread_mutex_lock)(mutex); } INTERCEPTOR(int, pthread_mutex_unlock, pthread_mutex_t *mutex) { - radsan::expectNotRealtime("pthread_mutex_unlock"); + radsan::ExpectNotRealtime("pthread_mutex_unlock"); return REAL(pthread_mutex_unlock)(mutex); } INTERCEPTOR(int, pthread_join, pthread_t thread, void **value_ptr) { - radsan::expectNotRealtime("pthread_join"); + radsan::ExpectNotRealtime("pthread_join"); return REAL(pthread_join)(thread, value_ptr); } INTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *cond) { - radsan::expectNotRealtime("pthread_cond_signal"); + radsan::ExpectNotRealtime("pthread_cond_signal"); return REAL(pthread_cond_signal)(cond); } INTERCEPTOR(int, pthread_cond_broadcast, pthread_cond_t *cond) { - radsan::expectNotRealtime("pthread_cond_broadcast"); + radsan::ExpectNotRealtime("pthread_cond_broadcast"); return REAL(pthread_cond_broadcast)(cond); } INTERCEPTOR(int, pthread_cond_wait, pthread_cond_t *cond, pthread_mutex_t *mutex) { - radsan::expectNotRealtime("pthread_cond_wait"); + radsan::ExpectNotRealtime("pthread_cond_wait"); return REAL(pthread_cond_wait)(cond, mutex); } INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *cond, pthread_mutex_t *mutex, const timespec *ts) { - radsan::expectNotRealtime("pthread_cond_timedwait"); + radsan::ExpectNotRealtime("pthread_cond_timedwait"); return REAL(pthread_cond_timedwait)(cond, mutex, ts); } INTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *lock) { - radsan::expectNotRealtime("pthread_rwlock_rdlock"); + radsan::ExpectNotRealtime("pthread_rwlock_rdlock"); return REAL(pthread_rwlock_rdlock)(lock); } INTERCEPTOR(int, pthread_rwlock_unlock, pthread_rwlock_t *lock) { - radsan::expectNotRealtime("pthread_rwlock_unlock"); + radsan::ExpectNotRealtime("pthread_rwlock_unlock"); return REAL(pthread_rwlock_unlock)(lock); } INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) { - radsan::expectNotRealtime("pthread_rwlock_wrlock"); + radsan::ExpectNotRealtime("pthread_rwlock_wrlock"); return REAL(pthread_rwlock_wrlock)(lock); } @@ -233,18 +230,18 @@ INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) { */ INTERCEPTOR(unsigned int, sleep, unsigned int s) { - radsan::expectNotRealtime("sleep"); + radsan::ExpectNotRealtime("sleep"); return REAL(sleep)(s); } INTERCEPTOR(int, usleep, useconds_t u) { - radsan::expectNotRealtime("usleep"); + radsan::ExpectNotRealtime("usleep"); return REAL(usleep)(u); } INTERCEPTOR(int, nanosleep, const struct timespec *rqtp, struct timespec *rmtp) { - radsan::expectNotRealtime("nanosleep"); + radsan::ExpectNotRealtime("nanosleep"); return REAL(nanosleep)(rqtp, rmtp); } @@ -253,40 +250,40 @@ INTERCEPTOR(int, nanosleep, const struct timespec *rqtp, */ INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) { - radsan::expectNotRealtime("calloc"); + radsan::ExpectNotRealtime("calloc"); return REAL(calloc)(num, size); } INTERCEPTOR(void, free, void *ptr) { if (ptr != NULL) { - radsan::expectNotRealtime("free"); + radsan::ExpectNotRealtime("free"); } return REAL(free)(ptr); } INTERCEPTOR(void *, malloc, SIZE_T size) { - radsan::expectNotRealtime("malloc"); + radsan::ExpectNotRealtime("malloc"); return REAL(malloc)(size); } INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) { - radsan::expectNotRealtime("realloc"); + radsan::ExpectNotRealtime("realloc"); return REAL(realloc)(ptr, size); } INTERCEPTOR(void *, reallocf, void *ptr, SIZE_T size) { - radsan::expectNotRealtime("reallocf"); + radsan::ExpectNotRealtime("reallocf"); return REAL(reallocf)(ptr, size); } INTERCEPTOR(void *, valloc, SIZE_T size) { - radsan::expectNotRealtime("valloc"); + radsan::ExpectNotRealtime("valloc"); return REAL(valloc)(size); } #if SANITIZER_INTERCEPT_ALIGNED_ALLOC INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) { - radsan::expectNotRealtime("aligned_alloc"); + radsan::ExpectNotRealtime("aligned_alloc"); return REAL(aligned_alloc)(alignment, size); } #define RADSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc) @@ -295,20 +292,20 @@ INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) { #endif INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) { - radsan::expectNotRealtime("posix_memalign"); + radsan::ExpectNotRealtime("posix_memalign"); return REAL(posix_memalign)(memptr, alignment, size); } #if SANITIZER_INTERCEPT_MEMALIGN INTERCEPTOR(void *, memalign, size_t alignment, size_t size) { - radsan::expectNotRealtime("memalign"); + radsan::ExpectNotRealtime("memalign"); return REAL(memalign)(alignment, size); } #endif #if SANITIZER_INTERCEPT_PVALLOC INTERCEPTOR(void *, pvalloc, size_t size) { - radsan::expectNotRealtime("pvalloc"); + radsan::ExpectNotRealtime("pvalloc"); return REAL(pvalloc)(size); } #endif @@ -318,45 +315,45 @@ INTERCEPTOR(void *, pvalloc, size_t size) { */ INTERCEPTOR(int, socket, int domain, int type, int protocol) { - radsan::expectNotRealtime("socket"); + radsan::ExpectNotRealtime("socket"); return REAL(socket)(domain, type, protocol); } INTERCEPTOR(ssize_t, send, int sockfd, const void *buf, size_t len, int flags) { - radsan::expectNotRealtime("send"); + radsan::ExpectNotRealtime("send"); return REAL(send)(sockfd, buf, len, flags); } INTERCEPTOR(ssize_t, sendmsg, int socket, const struct msghdr *message, int flags) { - radsan::expectNotRealtime("sendmsg"); + radsan::ExpectNotRealtime("sendmsg"); return REAL(sendmsg)(socket, message, flags); } INTERCEPTOR(ssize_t, sendto, int socket, const void *buffer, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len) { - radsan::expectNotRealtime("sendto"); + radsan::ExpectNotRealtime("sendto"); return REAL(sendto)(socket, buffer, length, flags, dest_addr, dest_len); } INTERCEPTOR(ssize_t, recv, int socket, void *buffer, size_t length, int flags) { - radsan::expectNotRealtime("recv"); + radsan::ExpectNotRealtime("recv"); return REAL(recv)(socket, buffer, length, flags); } INTERCEPTOR(ssize_t, recvfrom, int socket, void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len) { - radsan::expectNotRealtime("recvfrom"); + radsan::ExpectNotRealtime("recvfrom"); return REAL(recvfrom)(socket, buffer, length, flags, address, address_len); } INTERCEPTOR(ssize_t, recvmsg, int socket, struct msghdr *message, int flags) { - radsan::expectNotRealtime("recvmsg"); + radsan::ExpectNotRealtime("recvmsg"); return REAL(recvmsg)(socket, message, flags); } INTERCEPTOR(int, shutdown, int socket, int how) { - radsan::expectNotRealtime("shutdown"); + radsan::ExpectNotRealtime("shutdown"); return REAL(shutdown)(socket, how); } diff --git a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp index 5bf48362f819a..e5106832b81f1 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp @@ -12,56 +12,56 @@ TEST(TestRadsanContext, canCreateContext) { auto context = radsan::Context{}; } -TEST(TestRadsanContext, expectNotRealtimeDoesNotDieBeforeRealtimePush) { +TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieBeforeRealtimePush) { auto context = radsan::Context{}; - context.expectNotRealtime("do_some_stuff"); + context.ExpectNotRealtime("do_some_stuff"); } -TEST(TestRadsanContext, expectNotRealtimeDoesNotDieAfterPushAndPop) { +TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterPushAndPop) { auto context = radsan::Context{}; - context.realtimePush(); - context.realtimePop(); - context.expectNotRealtime("do_some_stuff"); + context.RealtimePush(); + context.RealtimePop(); + context.ExpectNotRealtime("do_some_stuff"); } -TEST(TestRadsanContext, expectNotRealtimeDiesAfterRealtimePush) { +TEST(TestRadsanContext, ExpectNotRealtimeDiesAfterRealtimePush) { auto context = radsan::Context{}; - context.realtimePush(); - EXPECT_DEATH(context.expectNotRealtime("do_some_stuff"), ""); + context.RealtimePush(); + EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), ""); } TEST(TestRadsanContext, - expectNotRealtimeDiesAfterRealtimeAfterMorePushesThanPops) { + ExpectNotRealtimeDiesAfterRealtimeAfterMorePushesThanPops) { auto context = radsan::Context{}; - context.realtimePush(); - context.realtimePush(); - context.realtimePush(); - context.realtimePop(); - context.realtimePop(); - EXPECT_DEATH(context.expectNotRealtime("do_some_stuff"), ""); + context.RealtimePush(); + context.RealtimePush(); + context.RealtimePush(); + context.RealtimePop(); + context.RealtimePop(); + EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), ""); } -TEST(TestRadsanContext, expectNotRealtimeDoesNotDieAfterBypassPush) { +TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) { auto context = radsan::Context{}; - context.realtimePush(); - context.bypassPush(); - context.expectNotRealtime("do_some_stuff"); + context.RealtimePush(); + context.BypassPush(); + context.ExpectNotRealtime("do_some_stuff"); } TEST(TestRadsanContext, - expectNotRealtimeDoesNotDieIfBypassDepthIsGreaterThanZero) { + ExpectNotRealtimeDoesNotDieIfBypassDepthIsGreaterThanZero) { auto context = radsan::Context{}; - context.realtimePush(); - context.bypassPush(); - context.bypassPush(); - context.bypassPush(); - context.bypassPop(); - context.bypassPop(); - context.expectNotRealtime("do_some_stuff"); - context.bypassPop(); - EXPECT_DEATH(context.expectNotRealtime("do_some_stuff"), ""); + context.RealtimePush(); + context.BypassPush(); + context.BypassPush(); + context.BypassPush(); + context.BypassPop(); + context.BypassPop(); + context.ExpectNotRealtime("do_some_stuff"); + context.BypassPop(); + EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), ""); } From 57532bbd8f93ce45cbd1aa4652eda5297a7387e9 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Tue, 7 May 2024 15:54:08 -0700 Subject: [PATCH 03/47] Another round of style cleanups --- compiler-rt/lib/radsan/radsan.cpp | 18 +++--- compiler-rt/lib/radsan/radsan.h | 12 ++-- compiler-rt/lib/radsan/radsan_context.cpp | 4 +- compiler-rt/lib/radsan/radsan_context.h | 2 +- .../lib/radsan/radsan_interceptors.cpp | 4 +- compiler-rt/lib/radsan/radsan_interceptors.h | 2 +- compiler-rt/lib/radsan/radsan_stack.cpp | 12 ++-- compiler-rt/lib/radsan/radsan_stack.h | 2 +- compiler-rt/lib/radsan/tests/radsan_test.cpp | 4 +- .../lib/radsan/tests/radsan_test_context.cpp | 62 +++++++++---------- .../radsan/tests/radsan_test_interceptors.cpp | 2 +- .../lib/radsan/tests/radsan_test_utilities.h | 16 ++--- 12 files changed, 70 insertions(+), 70 deletions(-) diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp index 273c81fafa549..3efdc24a33d17 100644 --- a/compiler-rt/lib/radsan/radsan.cpp +++ b/compiler-rt/lib/radsan/radsan.cpp @@ -12,21 +12,21 @@ #include extern "C" { -RADSAN_EXPORT void radsan_init() { radsan::initialiseInterceptors(); } +SANITIZER_INTERFACE_ATTRIBUTE void radsan_init() { radsan::InitializeInterceptors(); } -RADSAN_EXPORT void radsan_realtime_enter() { - radsan::getContextForThisThread().RealtimePush(); +SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter() { + radsan::GetContextForThisThread().RealtimePush(); } -RADSAN_EXPORT void radsan_realtime_exit() { - radsan::getContextForThisThread().RealtimePop(); +SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_exit() { + radsan::GetContextForThisThread().RealtimePop(); } -RADSAN_EXPORT void radsan_off() { - radsan::getContextForThisThread().BypassPush(); +SANITIZER_INTERFACE_ATTRIBUTE void radsan_off() { + radsan::GetContextForThisThread().BypassPush(); } -RADSAN_EXPORT void radsan_on() { - radsan::getContextForThisThread().BypassPop(); +SANITIZER_INTERFACE_ATTRIBUTE void radsan_on() { + radsan::GetContextForThisThread().BypassPop(); } } diff --git a/compiler-rt/lib/radsan/radsan.h b/compiler-rt/lib/radsan/radsan.h index 853cddc6927ec..79805a3be61e5 100644 --- a/compiler-rt/lib/radsan/radsan.h +++ b/compiler-rt/lib/radsan/radsan.h @@ -8,7 +8,7 @@ #pragma once -#define RADSAN_EXPORT __attribute__((visibility("default"))) +#include "sanitizer_common/sanitizer_internal_defs.h" extern "C" { @@ -18,7 +18,7 @@ extern "C" { @warning Do not call this method as a user. */ -RADSAN_EXPORT void radsan_init(); +SANITIZER_INTERFACE_ATTRIBUTE void radsan_init(); /** Enter real-time context. @@ -28,7 +28,7 @@ RADSAN_EXPORT void radsan_init(); @warning Do not call this method as a user */ -RADSAN_EXPORT void radsan_realtime_enter(); +SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter(); /** Exit the real-time context. @@ -37,7 +37,7 @@ RADSAN_EXPORT void radsan_realtime_enter(); @warning Do not call this method as a user */ -RADSAN_EXPORT void radsan_realtime_exit(); +SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_exit(); /** Disable all RADSan error reporting. @@ -62,12 +62,12 @@ RADSAN_EXPORT void radsan_realtime_exit(); } */ -RADSAN_EXPORT void radsan_off(); +SANITIZER_INTERFACE_ATTRIBUTE void radsan_off(); /** Re-enable all RADSan error reporting. The counterpart to `radsan_off`. See the description for `radsan_off` for details about how to use this method. */ -RADSAN_EXPORT void radsan_on(); +SANITIZER_INTERFACE_ATTRIBUTE void radsan_on(); } diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp index c84d64ee678fa..2c27e32eee689 100644 --- a/compiler-rt/lib/radsan/radsan_context.cpp +++ b/compiler-rt/lib/radsan/radsan_context.cpp @@ -58,10 +58,10 @@ void Context::PrintDiagnostics(const char *InterceptedFunctionName) { "Real-time violation: intercepted call to real-time unsafe function " "`%s` in real-time context! Stack trace:\n", InterceptedFunctionName); - radsan::printStackTrace(); + radsan::PrintStackTrace(); } -Context &getContextForThisThread() { +Context &GetContextForThisThread() { auto MakeTlsKey = []() { CHECK_EQ(pthread_key_create(&detail::Key, detail::internalFree), 0); }; diff --git a/compiler-rt/lib/radsan/radsan_context.h b/compiler-rt/lib/radsan/radsan_context.h index fd522a5974e5f..d06dce9f3d668 100644 --- a/compiler-rt/lib/radsan/radsan_context.h +++ b/compiler-rt/lib/radsan/radsan_context.h @@ -31,6 +31,6 @@ class Context { int BypassDepth{0}; }; -Context &getContextForThisThread(); +Context &GetContextForThisThread(); } // namespace radsan diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp index 4e06d20cbdcbf..8c3cfb010050f 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.cpp +++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp @@ -39,7 +39,7 @@ using namespace __sanitizer; namespace radsan { void ExpectNotRealtime(const char *InterceptedFunctionName) { - getContextForThisThread().ExpectNotRealtime(InterceptedFunctionName); + GetContextForThisThread().ExpectNotRealtime(InterceptedFunctionName); } } // namespace radsan @@ -362,7 +362,7 @@ INTERCEPTOR(int, shutdown, int socket, int how) { */ namespace radsan { -void initialiseInterceptors() { +void InitializeInterceptors() { INTERCEPT_FUNCTION(calloc); INTERCEPT_FUNCTION(free); INTERCEPT_FUNCTION(malloc); diff --git a/compiler-rt/lib/radsan/radsan_interceptors.h b/compiler-rt/lib/radsan/radsan_interceptors.h index 7a7471d3ad23b..6ce3943b40131 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.h +++ b/compiler-rt/lib/radsan/radsan_interceptors.h @@ -9,5 +9,5 @@ #pragma once namespace radsan { -void initialiseInterceptors(); +void InitializeInterceptors(); } diff --git a/compiler-rt/lib/radsan/radsan_stack.cpp b/compiler-rt/lib/radsan/radsan_stack.cpp index 4b9c98c6cb000..8330dbb4844b1 100644 --- a/compiler-rt/lib/radsan/radsan_stack.cpp +++ b/compiler-rt/lib/radsan/radsan_stack.cpp @@ -26,7 +26,7 @@ void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context, } // namespace __sanitizer namespace { -void setGlobalStackTraceFormat() { +void SetGlobalStackTraceFormat() { SetCommonFlagsDefaults(); CommonFlags cf; cf.CopyFrom(*common_flags()); @@ -37,14 +37,14 @@ void setGlobalStackTraceFormat() { } // namespace namespace radsan { -void printStackTrace() { +void PrintStackTrace() { - auto stack = BufferedStackTrace{}; + BufferedStackTrace Stack{}; GET_CURRENT_PC_BP; - stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal); + Stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal); - setGlobalStackTraceFormat(); - stack.Print(); + SetGlobalStackTraceFormat(); + Stack.Print(); } } // namespace radsan diff --git a/compiler-rt/lib/radsan/radsan_stack.h b/compiler-rt/lib/radsan/radsan_stack.h index 2f702079ff969..28bb1bc932fc9 100644 --- a/compiler-rt/lib/radsan/radsan_stack.h +++ b/compiler-rt/lib/radsan/radsan_stack.h @@ -9,5 +9,5 @@ #pragma once namespace radsan { -void printStackTrace(); +void PrintStackTrace(); } diff --git a/compiler-rt/lib/radsan/tests/radsan_test.cpp b/compiler-rt/lib/radsan/tests/radsan_test.cpp index 9e95110adaad9..a3d679a349a6b 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test.cpp @@ -150,7 +150,7 @@ TEST(TestRadsan, copyingALambdaWithLargeCaptureDiesWhenRealtime) { TEST(TestRadsan, accessingALargeAtomicVariableDiesWhenRealtime) { auto small_atomic = std::atomic{0.0f}; ASSERT_TRUE(small_atomic.is_lock_free()); - realtimeInvoke([&small_atomic]() { auto x = small_atomic.load(); }); + RealtimeInvoke([&small_atomic]() { auto x = small_atomic.load(); }); auto large_atomic = std::atomic>{{}}; ASSERT_FALSE(large_atomic.is_lock_free()); @@ -197,5 +197,5 @@ TEST(TestRadsan, doesNotDieIfTurnedOff) { mutex.unlock(); radsan_on(); }; - realtimeInvoke(realtime_unsafe_func); + RealtimeInvoke(realtime_unsafe_func); } diff --git a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp index e5106832b81f1..8b429b946947a 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp @@ -10,58 +10,58 @@ #include "radsan_context.h" -TEST(TestRadsanContext, canCreateContext) { auto context = radsan::Context{}; } +TEST(TestRadsanContext, CanCreateContext) { radsan::Context Context{}; } TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieBeforeRealtimePush) { - auto context = radsan::Context{}; - context.ExpectNotRealtime("do_some_stuff"); + radsan::Context Context{}; + Context.ExpectNotRealtime("do_some_stuff"); } TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterPushAndPop) { - auto context = radsan::Context{}; - context.RealtimePush(); - context.RealtimePop(); - context.ExpectNotRealtime("do_some_stuff"); + radsan::Context Context{}; + Context.RealtimePush(); + Context.RealtimePop(); + Context.ExpectNotRealtime("do_some_stuff"); } TEST(TestRadsanContext, ExpectNotRealtimeDiesAfterRealtimePush) { - auto context = radsan::Context{}; + radsan::Context Context{}; - context.RealtimePush(); - EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), ""); + Context.RealtimePush(); + EXPECT_DEATH(Context.ExpectNotRealtime("do_some_stuff"), ""); } TEST(TestRadsanContext, ExpectNotRealtimeDiesAfterRealtimeAfterMorePushesThanPops) { - auto context = radsan::Context{}; + radsan::Context Context{}; - context.RealtimePush(); - context.RealtimePush(); - context.RealtimePush(); - context.RealtimePop(); - context.RealtimePop(); - EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), ""); + Context.RealtimePush(); + Context.RealtimePush(); + Context.RealtimePush(); + Context.RealtimePop(); + Context.RealtimePop(); + EXPECT_DEATH(Context.ExpectNotRealtime("do_some_stuff"), ""); } TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) { - auto context = radsan::Context{}; + radsan::Context Context{}; - context.RealtimePush(); - context.BypassPush(); - context.ExpectNotRealtime("do_some_stuff"); + Context.RealtimePush(); + Context.BypassPush(); + Context.ExpectNotRealtime("do_some_stuff"); } TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieIfBypassDepthIsGreaterThanZero) { - auto context = radsan::Context{}; + radsan::Context Context{}; - context.RealtimePush(); - context.BypassPush(); - context.BypassPush(); - context.BypassPush(); - context.BypassPop(); - context.BypassPop(); - context.ExpectNotRealtime("do_some_stuff"); - context.BypassPop(); - EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), ""); + Context.RealtimePush(); + Context.BypassPush(); + Context.BypassPush(); + Context.BypassPush(); + Context.BypassPop(); + Context.BypassPop(); + Context.ExpectNotRealtime("do_some_stuff"); + Context.BypassPop(); + EXPECT_DEATH(Context.ExpectNotRealtime("do_some_stuff"), ""); } diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp index 316c294ba8294..989800ef7fc57 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp @@ -114,7 +114,7 @@ TEST(TestRadsanInterceptors, freeDiesWhenRealtime) { } TEST(TestRadsanInterceptors, freeSurvivesWhenRealtimeIfArgumentIsNull) { - realtimeInvoke([]() { free(NULL); }); + RealtimeInvoke([]() { free(NULL); }); expectNonrealtimeSurvival([]() { free(NULL); }); } diff --git a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h index fb50ee77156e9..1c1d8908fa92a 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h +++ b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h @@ -14,17 +14,17 @@ namespace radsan_testing { template -[[clang::realtime]] void realtimeInvoke(Function &&func) { - std::forward(func)(); +[[clang::realtime]] void RealtimeInvoke(Function &&Func) { + std::forward(Func)(); } template -void expectRealtimeDeath(Function &&func, +void expectRealtimeDeath(Function &&Func, const char *intercepted_method_name = nullptr) { using namespace testing; - auto expected_error_substr = [&]() -> std::string { + auto ExpectedErrorSubstring = [&]() -> std::string { return intercepted_method_name != nullptr ? "Real-time violation: intercepted call to real-time unsafe " "function `" + @@ -32,12 +32,12 @@ void expectRealtimeDeath(Function &&func, : ""; }; - EXPECT_EXIT(realtimeInvoke(std::forward(func)), - ExitedWithCode(EXIT_FAILURE), expected_error_substr()); + EXPECT_EXIT(RealtimeInvoke(std::forward(Func)), + ExitedWithCode(EXIT_FAILURE), ExpectedErrorSubstring()); } -template void expectNonrealtimeSurvival(Function &&func) { - std::forward(func)(); +template void expectNonrealtimeSurvival(Function &&Func) { + std::forward(Func)(); } } // namespace radsan_testing From 46681535ed9646448d273f5709c687631871edc3 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Tue, 7 May 2024 16:10:47 -0700 Subject: [PATCH 04/47] more auto removal, more case fixing --- compiler-rt/lib/radsan/tests/radsan_test.cpp | 8 +- .../radsan/tests/radsan_test_interceptors.cpp | 546 ++++++++---------- 2 files changed, 260 insertions(+), 294 deletions(-) diff --git a/compiler-rt/lib/radsan/tests/radsan_test.cpp b/compiler-rt/lib/radsan/tests/radsan_test.cpp index a3d679a349a6b..1bef709b454d0 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test.cpp @@ -63,14 +63,14 @@ TEST(TestRadsan, sleepingAThreadDiesWhenRealtime) { } TEST(TestRadsan, ifstreamCreationDiesWhenRealtime) { - auto func = []() { auto ifs = std::ifstream("./file.txt"); }; + auto func = []() { std::ifstream ifs{"./file.txt"}; }; expectRealtimeDeath(func); expectNonrealtimeSurvival(func); std::remove("./file.txt"); } TEST(TestRadsan, ofstreamCreationDiesWhenRealtime) { - auto func = []() { auto ofs = std::ofstream("./file.txt"); }; + auto func = []() { std::ofstream ofs{"./file.txt"}; }; expectRealtimeDeath(func); expectNonrealtimeSurvival(func); std::remove("./file.txt"); @@ -127,8 +127,8 @@ TEST(TestRadsan, sharedUnlockingASharedMutexDiesWhenRealtime) { TEST(TestRadsan, launchingAThreadDiesWhenRealtime) { auto func = [&]() { - auto t = std::thread([]() {}); - t.join(); + std::thread Thread{[]() {}}; + Thread.join(); }; expectRealtimeDeath(func); expectNonrealtimeSurvival(func); diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp index 989800ef7fc57..00a6153f3ccdd 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp @@ -37,7 +37,22 @@ using namespace radsan_testing; using namespace std::chrono_literals; namespace { -void *fake_thread_entry_point(void *) { return nullptr; } +void *FakeThreadEntryPoint(void *) { return nullptr; } + +/* + The creat function doesn't seem to work on an ubuntu Docker image when the + path is in a shared volume of the host. For now, to keep testing convenient + with a local Docker container, we just put it somewhere that's not in the + shared volume (/tmp). This is volatile and will be cleaned up as soon as the + container is stopped. +*/ +constexpr const char *TemporaryFilePath() { +#if SANITIZER_LINUX + return "/tmp/radsan_temporary_test_file.txt"; +#elif SANITIZER_APPLE + return "./radsan_temporary_test_file.txt"; +#endif +} } // namespace class RadsanFileTest : public ::testing::Test { @@ -65,46 +80,46 @@ class RadsanFileTest : public ::testing::Test { Allocation and deallocation */ -TEST(TestRadsanInterceptors, mallocDiesWhenRealtime) { - auto func = []() { EXPECT_NE(nullptr, malloc(1)); }; - expectRealtimeDeath(func, "malloc"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, MallocDiesWhenRealtime) { + auto Func = []() { EXPECT_NE(nullptr, malloc(1)); }; + expectRealtimeDeath(Func, "malloc"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, reallocDiesWhenRealtime) { - auto *ptr_1 = malloc(1); - auto func = [ptr_1]() { EXPECT_NE(nullptr, realloc(ptr_1, 8)); }; - expectRealtimeDeath(func, "realloc"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, ReallocDiesWhenRealtime) { + void *ptr_1 = malloc(1); + auto Func = [ptr_1]() { EXPECT_NE(nullptr, realloc(ptr_1, 8)); }; + expectRealtimeDeath(Func, "realloc"); + expectNonrealtimeSurvival(Func); } #if SANITIZER_APPLE -TEST(TestRadsanInterceptors, reallocfDiesWhenRealtime) { - auto *ptr_1 = malloc(1); - auto func = [ptr_1]() { EXPECT_NE(nullptr, reallocf(ptr_1, 8)); }; - expectRealtimeDeath(func, "reallocf"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, ReallocfDiesWhenRealtime) { + void *ptr_1 = malloc(1); + auto Func = [ptr_1]() { EXPECT_NE(nullptr, reallocf(ptr_1, 8)); }; + expectRealtimeDeath(Func, "reallocf"); + expectNonrealtimeSurvival(Func); } #endif -TEST(TestRadsanInterceptors, vallocDiesWhenRealtime) { - auto func = []() { EXPECT_NE(nullptr, valloc(4)); }; - expectRealtimeDeath(func, "valloc"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, VallocDiesWhenRealtime) { + auto Func = []() { EXPECT_NE(nullptr, valloc(4)); }; + expectRealtimeDeath(Func, "valloc"); + expectNonrealtimeSurvival(Func); } #if SANITIZER_INTERCEPT_ALIGNED_ALLOC -TEST(TestRadsanInterceptors, alignedAllocDiesWhenRealtime) { - auto func = []() { EXPECT_NE(nullptr, aligned_alloc(16, 32)); }; - expectRealtimeDeath(func, "aligned_alloc"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, AlignedAllocDiesWhenRealtime) { + auto Func = []() { EXPECT_NE(nullptr, aligned_alloc(16, 32)); }; + expectRealtimeDeath(Func, "aligned_alloc"); + expectNonrealtimeSurvival(Func); } #endif // free_sized and free_aligned_sized (both C23) are not yet supported -TEST(TestRadsanInterceptors, freeDiesWhenRealtime) { - auto *ptr_1 = malloc(1); - auto *ptr_2 = malloc(1); +TEST(TestRadsanInterceptors, FreeDiesWhenRealtime) { + void *ptr_1 = malloc(1); + void *ptr_2 = malloc(1); expectRealtimeDeath([ptr_1]() { free(ptr_1); }, "free"); expectNonrealtimeSurvival([ptr_2]() { free(ptr_2); }); @@ -113,33 +128,33 @@ TEST(TestRadsanInterceptors, freeDiesWhenRealtime) { ASSERT_NE(nullptr, ptr_2); } -TEST(TestRadsanInterceptors, freeSurvivesWhenRealtimeIfArgumentIsNull) { +TEST(TestRadsanInterceptors, FreeSurvivesWhenRealtimeIfArgumentIsNull) { RealtimeInvoke([]() { free(NULL); }); expectNonrealtimeSurvival([]() { free(NULL); }); } -TEST(TestRadsanInterceptors, posixMemalignDiesWhenRealtime) { - auto func = []() { - void *mem; - posix_memalign(&mem, 4, 4); +TEST(TestRadsanInterceptors, PosixMemalignDiesWhenRealtime) { + auto Func = []() { + void *Mem; + posix_memalign(&Mem, 4, 4); }; - expectRealtimeDeath(func, "posix_memalign"); - expectNonrealtimeSurvival(func); + expectRealtimeDeath(Func, "posix_memalign"); + expectNonrealtimeSurvival(Func); } #if SANITIZER_INTERCEPT_MEMALIGN -TEST(TestRadsanInterceptors, memalignDiesWhenRealtime) { - auto func = []() { EXPECT_NE(memalign(2, 2048), nullptr); }; - expectRealtimeDeath(func, "memalign"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, MemalignDiesWhenRealtime) { + auto Func = []() { EXPECT_NE(memalign(2, 2048), nullptr); }; + expectRealtimeDeath(Func, "memalign"); + expectNonrealtimeSurvival(Func); } #endif #if SANITIZER_INTERCEPT_PVALLOC -TEST(TestRadsanInterceptors, pvallocDiesWhenRealtime) { - auto func = []() { EXPECT_NE(pvalloc(2048), nullptr); }; - expectRealtimeDeath(func, "pvalloc"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, PvallocDiesWhenRealtime) { + auto Func = []() { EXPECT_NE(pvalloc(2048), nullptr); }; + expectRealtimeDeath(Func, "pvalloc"); + expectNonrealtimeSurvival(Func); } #endif @@ -147,215 +162,166 @@ TEST(TestRadsanInterceptors, pvallocDiesWhenRealtime) { Sleeping */ -TEST(TestRadsanInterceptors, sleepDiesWhenRealtime) { - auto func = []() { sleep(0u); }; - expectRealtimeDeath(func, "sleep"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, SleepDiesWhenRealtime) { + auto Func = []() { sleep(0u); }; + expectRealtimeDeath(Func, "sleep"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, usleepDiesWhenRealtime) { - auto func = []() { usleep(1u); }; - expectRealtimeDeath(func, "usleep"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, UsleepDiesWhenRealtime) { + auto Func = []() { usleep(1u); }; + expectRealtimeDeath(Func, "usleep"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, nanosleepDiesWhenRealtime) { - auto func = []() { - auto t = timespec{}; - nanosleep(&t, &t); +TEST(TestRadsanInterceptors, NanosleepDiesWhenRealtime) { + auto Func = []() { + timespec T{}; + nanosleep(&T, &T); }; - expectRealtimeDeath(func, "nanosleep"); - expectNonrealtimeSurvival(func); + expectRealtimeDeath(Func, "nanosleep"); + expectNonrealtimeSurvival(Func); } /* Filesystem */ -TEST_F(RadsanFileTest, openDiesWhenRealtime) { - auto func = [this]() { open(GetTemporaryFilePath(), O_RDONLY); }; - expectRealtimeDeath(func, "open"); - expectNonrealtimeSurvival(func); -} - -TEST_F(RadsanFileTest, openatDiesWhenRealtime) { - auto func = [this]() { openat(0, GetTemporaryFilePath(), O_RDONLY); }; - expectRealtimeDeath(func, "openat"); - expectNonrealtimeSurvival(func); -} - -TEST_F(RadsanFileTest, openCreatesFileWithProperMode) { - const int mode = S_IRGRP | S_IROTH | S_IRUSR | S_IWUSR; - - const int fd = open(GetTemporaryFilePath(), O_CREAT | O_WRONLY, mode); - ASSERT_THAT(fd, Ne(-1)); - close(fd); - - struct stat st; - ASSERT_THAT(stat(GetTemporaryFilePath(), &st), Eq(0)); - - // Mask st_mode to get permission bits only - ASSERT_THAT(st.st_mode & 0777, Eq(mode)); +TEST(TestRadsanInterceptors, OpenDiesWhenRealtime) { + auto Func = []() { open(TemporaryFilePath(), O_RDONLY); }; + ExpectRealtimeDeath(Func, "open"); + ExpectNonRealtimeSurvival(Func); + std::remove(TemporaryFilePath()); } -TEST_F(RadsanFileTest, creatDiesWhenRealtime) { - auto func = [this]() { creat(GetTemporaryFilePath(), S_IWOTH | S_IROTH); }; - expectRealtimeDeath(func, "creat"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, OpenatDiesWhenRealtime) { + auto Func = []() { openat(0, TemporaryFilePath(), O_RDONLY); }; + ExpectRealtimeDeath(Func, "openat"); + ExpectNonRealtimeSurvival(Func); + std::remove(TemporaryFilePath()); } -TEST(TestRadsanInterceptors, fcntlDiesWhenRealtime) { - auto func = []() { fcntl(0, F_GETFL); }; - expectRealtimeDeath(func, "fcntl"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, CreatDiesWhenRealtime) { + auto Func = []() { creat(TemporaryFilePath(), S_IWOTH | S_IROTH); }; + ExpectRealtimeDeath(Func, "creat"); + ExpectNonRealtimeSurvival(Func); + std::remove(TemporaryFilePath()); } -TEST_F(RadsanFileTest, fcntlFlockDiesWhenRealtime) { - int fd = creat(GetTemporaryFilePath(), S_IRUSR | S_IWUSR); - ASSERT_THAT(fd, Ne(-1)); - - auto func = [fd]() { - struct flock lock {}; - lock.l_type = F_RDLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; - lock.l_pid = ::getpid(); - - ASSERT_THAT(fcntl(fd, F_GETLK, &lock), Eq(0)); - ASSERT_THAT(lock.l_type, F_UNLCK); - }; - expectRealtimeDeath(func, "fcntl"); - expectNonrealtimeSurvival(func); - - close(fd); -} - -TEST_F(RadsanFileTest, fcntlSetFdDiesWhenRealtime) { - int fd = creat(GetTemporaryFilePath(), S_IRUSR | S_IWUSR); - ASSERT_THAT(fd, Ne(-1)); - - auto func = [fd]() { - int old_flags = fcntl(fd, F_GETFD); - ASSERT_THAT(fcntl(fd, F_SETFD, FD_CLOEXEC), Eq(0)); - - int flags = fcntl(fd, F_GETFD); - ASSERT_THAT(flags, Ne(-1)); - ASSERT_THAT(flags & FD_CLOEXEC, Eq(FD_CLOEXEC)); - - ASSERT_THAT(fcntl(fd, F_SETFD, old_flags), Eq(0)); - ASSERT_THAT(fcntl(fd, F_GETFD), Eq(old_flags)); - }; - - expectRealtimeDeath(func, "fcntl"); - expectNonrealtimeSurvival(func); - - close(fd); +TEST(TestRadsanInterceptors, FcntlDiesWhenRealtime) { + auto Func = []() { fcntl(0, F_GETFL); }; + ExpectRealtimeDeath(Func, "fcntl"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, closeDiesWhenRealtime) { - auto func = []() { close(0); }; - expectRealtimeDeath(func, "close"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, CloseDiesWhenRealtime) { + auto Func = []() { close(0); }; + expectRealtimeDeath(Func, "close"); + expectNonrealtimeSurvival(Func); } -TEST_F(RadsanFileTest, fopenDiesWhenRealtime) { - auto func = [this]() { - auto fd = fopen(GetTemporaryFilePath(), "w"); - EXPECT_THAT(fd, Ne(nullptr)); +TEST(TestRadsanInterceptors, FopenDiesWhenRealtime) { + auto Func = []() { + FILE* Fd = fopen(TemporaryFilePath(), "w"); + EXPECT_THAT(Fd, Ne(nullptr)); }; - expectRealtimeDeath(func, "fopen"); - expectNonrealtimeSurvival(func); + ExpectRealtimeDeath(Func, "fopen"); + ExpectNonRealtimeSurvival(Func); + std::remove(TemporaryFilePath()); } -TEST_F(RadsanFileTest, freadDiesWhenRealtime) { - auto fd = fopen(GetTemporaryFilePath(), "w"); - auto func = [fd]() { +TEST(TestRadsanInterceptors, FreadDiesWhenRealtime) { + FILE* Fd = fopen(TemporaryFilePath(), "w"); + auto Func = [Fd]() { char c{}; - fread(&c, 1, 1, fd); + fread(&c, 1, 1, Fd); }; - expectRealtimeDeath(func, "fread"); - expectNonrealtimeSurvival(func); - if (fd != nullptr) - fclose(fd); + ExpectRealtimeDeath(Func, "fread"); + ExpectNonRealtimeSurvival(Func); + if (Fd != nullptr) + fclose(Fd); + std::remove(TemporaryFilePath()); } -TEST_F(RadsanFileTest, fwriteDiesWhenRealtime) { - auto fd = fopen(GetTemporaryFilePath(), "w"); - ASSERT_NE(nullptr, fd); - auto message = "Hello, world!"; - auto func = [&]() { fwrite(&message, 1, 4, fd); }; - expectRealtimeDeath(func, "fwrite"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, FwriteDiesWhenRealtime) { + FILE* Fd = fopen(TemporaryFilePath(), "w"); + ASSERT_NE(nullptr, Fd); + const char* Message = "Hello, world!"; + auto Func = [&]() { fwrite(&Message, 1, 4, Fd); }; + ExpectRealtimeDeath(Func, "fwrite"); + ExpectNonRealtimeSurvival(Func); + std::remove(TemporaryFilePath()); } -TEST_F(RadsanFileTest, fcloseDiesWhenRealtime) { - auto fd = fopen(GetTemporaryFilePath(), "w"); - EXPECT_THAT(fd, Ne(nullptr)); - auto func = [fd]() { fclose(fd); }; - expectRealtimeDeath(func, "fclose"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, FcloseDiesWhenRealtime) { + FILE* Fd = fopen(TemporaryFilePath(), "w"); + EXPECT_THAT(Fd, Ne(nullptr)); + auto Func = [Fd]() { fclose(Fd); }; + ExpectRealtimeDeath(Func, "fclose"); + ExpectNonRealtimeSurvival(Func); + std::remove(TemporaryFilePath()); } -TEST(TestRadsanInterceptors, putsDiesWhenRealtime) { - auto func = []() { puts("Hello, world!\n"); }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, PutsDiesWhenRealtime) { + auto Func = []() { puts("Hello, world!\n"); }; + expectRealtimeDeath(Func); + expectNonrealtimeSurvival(Func); } -TEST_F(RadsanFileTest, fputsDiesWhenRealtime) { - auto fd = fopen(GetTemporaryFilePath(), "w"); - ASSERT_THAT(fd, Ne(nullptr)) << errno; - auto func = [fd]() { fputs("Hello, world!\n", fd); }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); - if (fd != nullptr) - fclose(fd); +TEST(TestRadsanInterceptors, FputsDiesWhenRealtime) { + FILE* Fd = fopen(TemporaryFilePath(), "w"); + ASSERT_THAT(Fd, Ne(nullptr)) << errno; + auto Func = [Fd]() { fputs("Hello, world!\n", Fd); }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); + if (Fd != nullptr) + fclose(Fd); + std::remove(TemporaryFilePath()); } /* Concurrency */ -TEST(TestRadsanInterceptors, pthreadCreateDiesWhenRealtime) { - auto func = []() { - auto thread = pthread_t{}; - auto const attr = pthread_attr_t{}; - struct thread_info *tinfo; - pthread_create(&thread, &attr, &fake_thread_entry_point, tinfo); +TEST(TestRadsanInterceptors, PthreadCreateDiesWhenRealtime) { + auto Func = []() { + pthread_t Thread{}; + const pthread_attr_t Attr{}; + struct thread_info *ThreadInfo; + pthread_create(&Thread, &Attr, &FakeThreadEntryPoint, ThreadInfo); }; - expectRealtimeDeath(func, "pthread_create"); - expectNonrealtimeSurvival(func); + expectRealtimeDeath(Func, "pthread_create"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, pthreadMutexLockDiesWhenRealtime) { - auto func = []() { - auto mutex = pthread_mutex_t{}; - pthread_mutex_lock(&mutex); +TEST(TestRadsanInterceptors, PthreadMutexLockDiesWhenRealtime) { + auto Func = []() { + pthread_mutex_t Mutex{}; + pthread_mutex_lock(&Mutex); }; - expectRealtimeDeath(func, "pthread_mutex_lock"); - expectNonrealtimeSurvival(func); + expectRealtimeDeath(Func, "pthread_mutex_lock"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, pthreadMutexUnlockDiesWhenRealtime) { - auto func = []() { - auto mutex = pthread_mutex_t{}; - pthread_mutex_unlock(&mutex); +TEST(TestRadsanInterceptors, PthreadMutexUnlockDiesWhenRealtime) { + auto Func = []() { + pthread_mutex_t Mutex{}; + pthread_mutex_unlock(&Mutex); }; - expectRealtimeDeath(func, "pthread_mutex_unlock"); - expectNonrealtimeSurvival(func); + expectRealtimeDeath(Func, "pthread_mutex_unlock"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, pthreadMutexJoinDiesWhenRealtime) { - auto func = []() { - auto thread = pthread_t{}; - pthread_join(thread, nullptr); +TEST(TestRadsanInterceptors, PthreadMutexJoinDiesWhenRealtime) { + auto Func = []() { + pthread_t Thread{}; + pthread_join(Thread, nullptr); }; - expectRealtimeDeath(func, "pthread_join"); - expectNonrealtimeSurvival(func); + expectRealtimeDeath(Func, "pthread_join"); + expectNonrealtimeSurvival(Func); } #if SANITIZER_APPLE @@ -363,146 +329,146 @@ TEST(TestRadsanInterceptors, pthreadMutexJoinDiesWhenRealtime) { #pragma clang diagnostic push // OSSpinLockLock is deprecated, but still in use in libc++ #pragma clang diagnostic ignored "-Wdeprecated-declarations" -TEST(TestRadsanInterceptors, osSpinLockLockDiesWhenRealtime) { - auto func = []() { - auto spin_lock = OSSpinLock{}; - OSSpinLockLock(&spin_lock); +TEST(TestRadsanInterceptors, OsSpinLockLockDiesWhenRealtime) { + auto Func = []() { + OSSpinLock SpinLock{}; + OSSpinLockLock(&SpinLock); }; - expectRealtimeDeath(func, "OSSpinLockLock"); - expectNonrealtimeSurvival(func); + expectRealtimeDeath(Func, "OSSpinLockLock"); + expectNonrealtimeSurvival(Func); } #pragma clang diagnostic pop -TEST(TestRadsanInterceptors, osUnfairLockLockDiesWhenRealtime) { - auto func = []() { - auto unfair_lock = os_unfair_lock_s{}; - os_unfair_lock_lock(&unfair_lock); +TEST(TestRadsanInterceptors, OsUnfairLockLockDiesWhenRealtime) { + auto Func = []() { + os_unfair_lock_s UnfairLock{}; + os_unfair_lock_lock(&UnfairLock); }; - expectRealtimeDeath(func, "os_unfair_lock_lock"); - expectNonrealtimeSurvival(func); + expectRealtimeDeath(Func, "os_unfair_lock_lock"); + expectNonrealtimeSurvival(Func); } #endif #if SANITIZER_LINUX -TEST(TestRadsanInterceptors, spinLockLockDiesWhenRealtime) { - auto spinlock = pthread_spinlock_t{}; - pthread_spin_init(&spinlock, PTHREAD_PROCESS_SHARED); - auto func = [&]() { pthread_spin_lock(&spinlock); }; - expectRealtimeDeath(func, "pthread_spin_lock"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, SpinLockLockDiesWhenRealtime) { + pthread_spinlock_t SpinLock; + pthread_spin_init(&SpinLock, PTHREAD_PROCESS_SHARED); + auto Func = [&]() { pthread_spin_lock(&SpinLock); }; + expectRealtimeDeath(Func, "pthread_spin_lock"); + expectNonrealtimeSurvival(Func); } #endif -TEST(TestRadsanInterceptors, pthreadCondSignalDiesWhenRealtime) { - auto func = []() { - auto cond = pthread_cond_t{}; - pthread_cond_signal(&cond); +TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) { + auto Func = []() { + pthread_cond_t Cond{}; + pthread_cond_signal(&Cond); }; - expectRealtimeDeath(func, "pthread_cond_signal"); - expectNonrealtimeSurvival(func); + expectRealtimeDeath(Func, "pthread_cond_signal"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, pthreadCondBroadcastDiesWhenRealtime) { - auto func = []() { - auto cond = pthread_cond_t{}; - pthread_cond_broadcast(&cond); +TEST(TestRadsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) { + auto Func = []() { + pthread_cond_t Cond; + pthread_cond_broadcast(&Cond); }; - expectRealtimeDeath(func, "pthread_cond_broadcast"); - expectNonrealtimeSurvival(func); + expectRealtimeDeath(Func, "pthread_cond_broadcast"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, pthreadCondWaitDiesWhenRealtime) { - auto cond = pthread_cond_t{}; - auto mutex = pthread_mutex_t{}; - ASSERT_EQ(0, pthread_cond_init(&cond, nullptr)); - ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr)); - auto func = [&]() { pthread_cond_wait(&cond, &mutex); }; - expectRealtimeDeath(func, "pthread_cond_wait"); +TEST(TestRadsanInterceptors, PthreadCondWaitDiesWhenRealtime) { + pthread_cond_t Cond; + pthread_mutex_t Mutex; + ASSERT_EQ(0, pthread_cond_init(&Cond, nullptr)); + ASSERT_EQ(0, pthread_mutex_init(&Mutex, nullptr)); + auto Func = [&]() { pthread_cond_wait(&Cond, &Mutex); }; + expectRealtimeDeath(Func, "pthread_cond_wait"); // It's very difficult to test the success case here without doing some // sleeping, which is at the mercy of the scheduler. What's really important // here is the interception - so we're only testing that for now. } -TEST(TestRadsanInterceptors, pthreadRwlockRdlockDiesWhenRealtime) { - auto func = []() { - auto rwlock = pthread_rwlock_t{}; - pthread_rwlock_rdlock(&rwlock); +TEST(TestRadsanInterceptors, PthreadRwlockRdlockDiesWhenRealtime) { + auto Func = []() { + pthread_rwlock_t RwLock; + pthread_rwlock_rdlock(&RwLock); }; - expectRealtimeDeath(func, "pthread_rwlock_rdlock"); - expectNonrealtimeSurvival(func); + expectRealtimeDeath(Func, "pthread_rwlock_rdlock"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, pthreadRwlockUnlockDiesWhenRealtime) { - auto func = []() { - auto rwlock = pthread_rwlock_t{}; - pthread_rwlock_unlock(&rwlock); +TEST(TestRadsanInterceptors, PthreadRwlockUnlockDiesWhenRealtime) { + auto Func = []() { + pthread_rwlock_t RwLock; + pthread_rwlock_unlock(&RwLock); }; - expectRealtimeDeath(func, "pthread_rwlock_unlock"); - expectNonrealtimeSurvival(func); + expectRealtimeDeath(Func, "pthread_rwlock_unlock"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, pthreadRwlockWrlockDiesWhenRealtime) { - auto func = []() { - auto rwlock = pthread_rwlock_t{}; - pthread_rwlock_wrlock(&rwlock); +TEST(TestRadsanInterceptors, PthreadRwlockWrlockDiesWhenRealtime) { + auto Func = []() { + pthread_rwlock_t RwLock; + pthread_rwlock_wrlock(&RwLock); }; - expectRealtimeDeath(func, "pthread_rwlock_wrlock"); - expectNonrealtimeSurvival(func); + expectRealtimeDeath(Func, "pthread_rwlock_wrlock"); + expectNonrealtimeSurvival(Func); } /* Sockets */ -TEST(TestRadsanInterceptors, openingASocketDiesWhenRealtime) { - auto func = []() { socket(PF_INET, SOCK_STREAM, 0); }; - expectRealtimeDeath(func, "socket"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, OpeningASocketDiesWhenRealtime) { + auto Func = []() { socket(PF_INET, SOCK_STREAM, 0); }; + expectRealtimeDeath(Func, "socket"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, sendToASocketDiesWhenRealtime) { - auto func = []() { send(0, nullptr, 0, 0); }; - expectRealtimeDeath(func, "send"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, SendToASocketDiesWhenRealtime) { + auto Func = []() { send(0, nullptr, 0, 0); }; + expectRealtimeDeath(Func, "send"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, sendmsgToASocketDiesWhenRealtime) { - auto const msg = msghdr{}; - auto func = [&]() { sendmsg(0, &msg, 0); }; - expectRealtimeDeath(func, "sendmsg"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, SendmsgToASocketDiesWhenRealtime) { + msghdr Msg{}; + auto Func = [&]() { sendmsg(0, &Msg, 0); }; + expectRealtimeDeath(Func, "sendmsg"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, sendtoToASocketDiesWhenRealtime) { - auto const addr = sockaddr{}; - auto const len = socklen_t{}; - auto func = [&]() { sendto(0, nullptr, 0, 0, &addr, len); }; - expectRealtimeDeath(func, "sendto"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, SendtoToASocketDiesWhenRealtime) { + sockaddr Addr{}; + socklen_t Len{}; + auto Func = [&]() { sendto(0, nullptr, 0, 0, &Addr, Len); }; + expectRealtimeDeath(Func, "sendto"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, recvFromASocketDiesWhenRealtime) { - auto func = []() { recv(0, nullptr, 0, 0); }; - expectRealtimeDeath(func, "recv"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, RecvFromASocketDiesWhenRealtime) { + auto Func = []() { recv(0, nullptr, 0, 0); }; + expectRealtimeDeath(Func, "recv"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, recvfromOnASocketDiesWhenRealtime) { - auto addr = sockaddr{}; - auto len = socklen_t{}; - auto func = [&]() { recvfrom(0, nullptr, 0, 0, &addr, &len); }; - expectRealtimeDeath(func, "recvfrom"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, RecvfromOnASocketDiesWhenRealtime) { + sockaddr Addr{}; + socklen_t Len{}; + auto Func = [&]() { recvfrom(0, nullptr, 0, 0, &Addr, &Len); }; + expectRealtimeDeath(Func, "recvfrom"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, recvmsgOnASocketDiesWhenRealtime) { - auto msg = msghdr{}; - auto func = [&]() { recvmsg(0, &msg, 0); }; - expectRealtimeDeath(func, "recvmsg"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, RecvmsgOnASocketDiesWhenRealtime) { + msghdr Msg{}; + auto Func = [&]() { recvmsg(0, &Msg, 0); }; + expectRealtimeDeath(Func, "recvmsg"); + expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, shutdownOnASocketDiesWhenRealtime) { - auto func = [&]() { shutdown(0, 0); }; - expectRealtimeDeath(func, "shutdown"); - expectNonrealtimeSurvival(func); +TEST(TestRadsanInterceptors, ShutdownOnASocketDiesWhenRealtime) { + auto Func = [&]() { shutdown(0, 0); }; + expectRealtimeDeath(Func, "shutdown"); + expectNonrealtimeSurvival(Func); } From 12924769c382b3a203ff012093e107a25f535b42 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Tue, 7 May 2024 16:15:32 -0700 Subject: [PATCH 05/47] Missing end of namespace comment --- compiler-rt/lib/radsan/radsan.cpp | 8 ++++++-- compiler-rt/lib/radsan/radsan.h | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp index 3efdc24a33d17..e5653d9f10d24 100644 --- a/compiler-rt/lib/radsan/radsan.cpp +++ b/compiler-rt/lib/radsan/radsan.cpp @@ -12,7 +12,10 @@ #include extern "C" { -SANITIZER_INTERFACE_ATTRIBUTE void radsan_init() { radsan::InitializeInterceptors(); } + +SANITIZER_INTERFACE_ATTRIBUTE void radsan_init() { + radsan::InitializeInterceptors(); +} SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter() { radsan::GetContextForThisThread().RealtimePush(); @@ -29,4 +32,5 @@ SANITIZER_INTERFACE_ATTRIBUTE void radsan_off() { SANITIZER_INTERFACE_ATTRIBUTE void radsan_on() { radsan::GetContextForThisThread().BypassPop(); } -} + +} // extern "C" diff --git a/compiler-rt/lib/radsan/radsan.h b/compiler-rt/lib/radsan/radsan.h index 79805a3be61e5..9a728156e0166 100644 --- a/compiler-rt/lib/radsan/radsan.h +++ b/compiler-rt/lib/radsan/radsan.h @@ -70,4 +70,5 @@ SANITIZER_INTERFACE_ATTRIBUTE void radsan_off(); details about how to use this method. */ SANITIZER_INTERFACE_ATTRIBUTE void radsan_on(); -} + +} // extern "C" From 47c7b7b7ca2fbac2f96ac77b0a697f9d4cd1b9ae Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Wed, 8 May 2024 12:16:29 -0700 Subject: [PATCH 06/47] Fix one naming issue --- compiler-rt/lib/radsan/radsan_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler-rt/lib/radsan/radsan_context.h b/compiler-rt/lib/radsan/radsan_context.h index d06dce9f3d668..5b874e74b8317 100644 --- a/compiler-rt/lib/radsan/radsan_context.h +++ b/compiler-rt/lib/radsan/radsan_context.h @@ -20,7 +20,7 @@ class Context { void BypassPush(); void BypassPop(); - void ExpectNotRealtime(const char *interpreted_function_name); + void ExpectNotRealtime(const char *InterceptedFunctionName); private: bool InRealtimeContext() const; From ddd517981f9832af81cef14efb72fcc2ba2b8bb4 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Mon, 13 May 2024 13:43:00 -0700 Subject: [PATCH 07/47] No more unistd --- compiler-rt/lib/radsan/radsan.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp index e5653d9f10d24..222ef62a9c60c 100644 --- a/compiler-rt/lib/radsan/radsan.cpp +++ b/compiler-rt/lib/radsan/radsan.cpp @@ -9,7 +9,6 @@ #include #include #include -#include extern "C" { From fab7170479ab8d241e5d6518966a9476d5e871d8 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Mon, 13 May 2024 13:43:18 -0700 Subject: [PATCH 08/47] Radsan context moved to impl --- compiler-rt/lib/radsan/radsan_context.cpp | 31 +++++++++++++---------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp index 2c27e32eee689..b29cac1059ee2 100644 --- a/compiler-rt/lib/radsan/radsan_context.cpp +++ b/compiler-rt/lib/radsan/radsan_context.cpp @@ -26,6 +26,23 @@ static pthread_key_t Key; static pthread_once_t KeyOnce = PTHREAD_ONCE_INIT; void internalFree(void *Ptr) { __sanitizer::InternalFree(Ptr); } +using radsan::Context; + +Context &GetContextForThisThreadImpl() { + auto MakeTlsKey = []() { + CHECK_EQ(pthread_key_create(&detail::Key, detail::internalFree), 0); + }; + + pthread_once(&detail::KeyOnce, MakeTlsKey); + Context *CurrentThreadContext = static_cast(pthread_getspecific(detail::Key)); + if (CurrentThreadContext == nullptr) { + CurrentThreadContext = static_cast(InternalAlloc(sizeof(Context))); + new(CurrentThreadContext) Context(); + pthread_setspecific(detail::Key, CurrentThreadContext); + } + + return *CurrentThreadContext; +} } // namespace detail namespace radsan { @@ -62,19 +79,7 @@ void Context::PrintDiagnostics(const char *InterceptedFunctionName) { } Context &GetContextForThisThread() { - auto MakeTlsKey = []() { - CHECK_EQ(pthread_key_create(&detail::Key, detail::internalFree), 0); - }; - - pthread_once(&detail::KeyOnce, MakeTlsKey); - Context *CurrentThreadContext = static_cast(pthread_getspecific(detail::Key)); - if (CurrentThreadContext == nullptr) { - CurrentThreadContext = static_cast(InternalAlloc(sizeof(Context))); - new(CurrentThreadContext) Context(); - pthread_setspecific(detail::Key, CurrentThreadContext); - } - - return *CurrentThreadContext; + return detail::GetContextForThisThreadImpl(); } } // namespace radsan From 3de5ba9286ca0038eb81922014d842c3cfb87b63 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Mon, 13 May 2024 14:02:36 -0700 Subject: [PATCH 09/47] Promise lit tests later --- compiler-rt/test/radsan/CMakeLists.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/compiler-rt/test/radsan/CMakeLists.txt b/compiler-rt/test/radsan/CMakeLists.txt index 51a3ff72859b6..d6b8dc9652879 100644 --- a/compiler-rt/test/radsan/CMakeLists.txt +++ b/compiler-rt/test/radsan/CMakeLists.txt @@ -1,3 +1,14 @@ + + + + +###### +# TODO: Full lit tests coming in a future review when we introduce the codegen +###### + + + + set(RADSAN_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(RADSAN_TESTSUITES) From f46daf4c1f4c4ea0e18ff5e50bf1da7de58a0b54 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Mon, 13 May 2024 14:05:57 -0700 Subject: [PATCH 10/47] Move radsan_test and add helper comment to top of file --- compiler-rt/lib/radsan/tests/CMakeLists.txt | 2 +- ...an_test.cpp => radsan_test_functional.cpp} | 20 ++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) rename compiler-rt/lib/radsan/tests/{radsan_test.cpp => radsan_test_functional.cpp} (89%) diff --git a/compiler-rt/lib/radsan/tests/CMakeLists.txt b/compiler-rt/lib/radsan/tests/CMakeLists.txt index 73cedac2765d6..79a3d2d3d6c23 100644 --- a/compiler-rt/lib/radsan/tests/CMakeLists.txt +++ b/compiler-rt/lib/radsan/tests/CMakeLists.txt @@ -15,7 +15,7 @@ set(RADSAN_UNITTEST_CFLAGS -O2) set(RADSAN_INST_TEST_SOURCES - radsan_test.cpp + radsan_test_functional.cpp radsan_test_interceptors.cpp radsan_test_main.cpp) diff --git a/compiler-rt/lib/radsan/tests/radsan_test.cpp b/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp similarity index 89% rename from compiler-rt/lib/radsan/tests/radsan_test.cpp rename to compiler-rt/lib/radsan/tests/radsan_test_functional.cpp index 1bef709b454d0..ed02e1e32cd2d 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp @@ -1,10 +1,16 @@ -/** - This file is part of the RealtimeSanitizer (RADSan) project. - https://github.com/realtime-sanitizer/radsan - - Copyright 2023 David Trevelyan & Alistair Barker - Subject to GNU General Public License (GPL) v3.0 -*/ +//===--- radsan_test.cpp - Realtime Sanitizer --------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Introduces basic functional tests for the realtime sanitizer. +// Not meant to be exhaustive, testing all interceptors, please see +// test_radsan_interceptors.cpp for those tests. +// +//===----------------------------------------------------------------------===// #include "gtest/gtest.h" From 07483d342e136aaaa2db0a84301483515a52d6aa Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Mon, 13 May 2024 14:06:13 -0700 Subject: [PATCH 11/47] Only link radsan statically --- clang/lib/Driver/ToolChains/CommonArgs.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index e56091119ac12..ecac13e821cec 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1439,8 +1439,6 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, if (!Args.hasArg(options::OPT_shared)) HelperStaticRuntimes.push_back("hwasan-preinit"); } - if (SanArgs.needsRadsanRt() && SanArgs.linkRuntimes()) - SharedRuntimes.push_back("radsan"); } // The stats_client library is also statically linked into DSOs. @@ -1466,7 +1464,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, StaticRuntimes.push_back("asan_cxx"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsRadsanRt() && SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsRadsanRt()) { StaticRuntimes.push_back("radsan"); } From 605e53d7b309a684f999382494f42454583654dd Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Wed, 15 May 2024 13:54:13 -0700 Subject: [PATCH 12/47] Fix comments in radsan.h --- compiler-rt/lib/radsan/radsan.h | 44 +++++++-------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) diff --git a/compiler-rt/lib/radsan/radsan.h b/compiler-rt/lib/radsan/radsan.h index 9a728156e0166..f8e248f8938d8 100644 --- a/compiler-rt/lib/radsan/radsan.h +++ b/compiler-rt/lib/radsan/radsan.h @@ -12,62 +12,36 @@ extern "C" { -/** - Initialise radsan interceptors. A call to this method is added to the - preinit array on Linux systems. +/** Initialise radsan interceptors. - @warning Do not call this method as a user. + A call to this method is added to the preinit array on Linux systems. */ SANITIZER_INTERFACE_ATTRIBUTE void radsan_init(); /** Enter real-time context. - When in a real-time context, RADSan interceptors will error if realtime - violations are detected. Calls to this method are injected at the code - generation stage when RADSan is enabled. - - @warning Do not call this method as a user + When in a real-time context, RADSan interceptors will error if realtime + violations are detected. Calls to this method are injected at the code + generation stage when RADSan is enabled. */ SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter(); /** Exit the real-time context. - When not in a real-time context, RADSan interceptors will simply forward - intercepted method calls to the real methods. - - @warning Do not call this method as a user + When not in a real-time context, RADSan interceptors will simply forward + intercepted method calls to the real methods. */ SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_exit(); /** Disable all RADSan error reporting. - This method might be useful to you if RADSan is presenting you with an error - for some code you are confident is realtime safe. For example, you might - know that a mutex is never contested, and that locking it will never block - on your particular system. Be careful! - - A call to `radsan_off()` MUST be paired with a corresponding `radsan_on()` - to reactivate interception after the code in question. If you don't, radsan - will cease to work. - - Example: - - [[clang::realtime]] float process (float x) - { - auto const y = 2.0f * x; - - radsan_off(); - i_know_this_method_is_realtime_safe_but_radsan_complains_about_it(); - radsan_on(); - } - + Injected into the code if "nosanitize(realtime)" is on a function. */ SANITIZER_INTERFACE_ATTRIBUTE void radsan_off(); /** Re-enable all RADSan error reporting. - The counterpart to `radsan_off`. See the description for `radsan_off` for - details about how to use this method. + The counterpart to `radsan_off`. */ SANITIZER_INTERFACE_ATTRIBUTE void radsan_on(); From 5976e9897ab8c420601ae6c11e638c8e2514e66a Mon Sep 17 00:00:00 2001 From: David Trevelyan Date: Thu, 16 May 2024 22:18:07 +0100 Subject: [PATCH 13/47] Replace inlined exit with selected action stub --- compiler-rt/lib/radsan/radsan_context.cpp | 27 +++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp index b29cac1059ee2..21b082c524774 100644 --- a/compiler-rt/lib/radsan/radsan_context.cpp +++ b/compiler-rt/lib/radsan/radsan_context.cpp @@ -34,15 +34,34 @@ Context &GetContextForThisThreadImpl() { }; pthread_once(&detail::KeyOnce, MakeTlsKey); - Context *CurrentThreadContext = static_cast(pthread_getspecific(detail::Key)); + Context *CurrentThreadContext = + static_cast(pthread_getspecific(detail::Key)); if (CurrentThreadContext == nullptr) { - CurrentThreadContext = static_cast(InternalAlloc(sizeof(Context))); - new(CurrentThreadContext) Context(); + CurrentThreadContext = + static_cast(InternalAlloc(sizeof(Context))); + new (CurrentThreadContext) Context(); pthread_setspecific(detail::Key, CurrentThreadContext); } return *CurrentThreadContext; } + +/* + This is a placeholder stub for a future feature that will allow + a user to configure RADSan's behaviour when a real-time safety + violation is detected. The RADSan developers intend for the + following choices to be made available, via a RADSAN_OPTIONS + environment variable, in a future PR: + + i) exit, + ii) continue, or + iii) wait for user input from stdin. + + Until then, and to keep the first PRs small, only the exit mode + is available. +*/ +void InvokeViolationDetectedAction() { exit(EXIT_FAILURE); } + } // namespace detail namespace radsan { @@ -61,7 +80,7 @@ void Context::ExpectNotRealtime(const char *InterceptedFunctionName) { if (InRealtimeContext() && !IsBypassed()) { BypassPush(); PrintDiagnostics(InterceptedFunctionName); - exit(EXIT_FAILURE); + detail::InvokeViolationDetectedAction(); BypassPop(); } } From 11ecbcb79726c0cbf52045c07db01e4ceea03e52 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Thu, 16 May 2024 13:54:01 -0700 Subject: [PATCH 14/47] Codeowners --- compiler-rt/CODE_OWNERS.TXT | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler-rt/CODE_OWNERS.TXT b/compiler-rt/CODE_OWNERS.TXT index ad136edf96781..2db0357fc1a7f 100644 --- a/compiler-rt/CODE_OWNERS.TXT +++ b/compiler-rt/CODE_OWNERS.TXT @@ -67,3 +67,7 @@ D: ThreadSanitizer N: Bill Wendling E: isanbard@gmail.com D: Profile runtime library + +N: Christopher Apple, David Trevelyan +E: cja-private@pm.me, realtime.sanitizer@gmail.com +D: Realtime Sanitizer (RADSan) From 519e0c7bf5ddeb30ca8b690419a23278ea9d769b Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Thu, 16 May 2024 14:40:46 -0700 Subject: [PATCH 15/47] Fix python formatting errors --- compiler-rt/test/radsan/lit.cfg.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler-rt/test/radsan/lit.cfg.py b/compiler-rt/test/radsan/lit.cfg.py index 773b624900fa6..32af62dfb8e04 100644 --- a/compiler-rt/test/radsan/lit.cfg.py +++ b/compiler-rt/test/radsan/lit.cfg.py @@ -40,7 +40,9 @@ def build_invocation(compile_flags): ("%clangxx ", build_invocation(config.cxx_mode_flags + [config.target_cflags])) ) config.substitutions.append(("%clang_radsan ", build_invocation(clang_radsan_cflags))) -config.substitutions.append(("%clangxx_radsan", build_invocation(clang_radsan_cxxflags))) +config.substitutions.append( + ("%clangxx_radsan", build_invocation(clang_radsan_cxxflags)) +) config.substitutions.append(("%llvm_radsan", llvm_radsan)) config.substitutions.append( ( From 7864f16ffedc10965fc11657527c2b82bf17d17a Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Thu, 16 May 2024 14:43:43 -0700 Subject: [PATCH 16/47] Fix cpp style issues --- clang/lib/Driver/ToolChains/Darwin.cpp | 6 ++-- compiler-rt/lib/radsan/radsan.cpp | 4 +-- .../lib/radsan/radsan_interceptors.cpp | 17 ++++++----- compiler-rt/lib/radsan/radsan_interceptors.h | 17 ++++++----- compiler-rt/lib/radsan/radsan_preinit.cpp | 4 +-- .../lib/radsan/tests/radsan_test_context.cpp | 17 ++++++----- .../radsan/tests/radsan_test_interceptors.cpp | 29 ++++++++++--------- .../lib/radsan/tests/radsan_test_utilities.h | 21 ++++++++------ 8 files changed, 65 insertions(+), 50 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index b75e6580890c1..b3e9d14021cda 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -1520,9 +1520,9 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, AddLinkSanitizerLibArgs(Args, CmdArgs, "asan"); } } - if(Sanitize.needsRadsanRt()) - { - assert(Sanitize.needsSharedRt() && "Static sanitizer runtimes not supported"); + if (Sanitize.needsRadsanRt()) { + assert(Sanitize.needsSharedRt() && + "Static sanitizer runtimes not supported"); AddLinkSanitizerLibArgs(Args, CmdArgs, "radsan"); } if (Sanitize.needsLsanRt()) diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp index 222ef62a9c60c..9d5c96a9b07b5 100644 --- a/compiler-rt/lib/radsan/radsan.cpp +++ b/compiler-rt/lib/radsan/radsan.cpp @@ -12,8 +12,8 @@ extern "C" { -SANITIZER_INTERFACE_ATTRIBUTE void radsan_init() { - radsan::InitializeInterceptors(); +SANITIZER_INTERFACE_ATTRIBUTE void radsan_init() { + radsan::InitializeInterceptors(); } SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter() { diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp index 8c3cfb010050f..57ac631060c4f 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.cpp +++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp @@ -1,10 +1,13 @@ -/** - This file is part of the RealtimeSanitizer (RADSan) project. - https://github.com/realtime-sanitizer/radsan - - Copyright 2023 David Trevelyan & Alistair Barker - Subject to GNU General Public License (GPL) v3.0 -*/ +//===--- radsan_interceptors.cpp - Realtime Sanitizer --------------*- C++ +//-*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// #include "radsan/radsan_interceptors.h" diff --git a/compiler-rt/lib/radsan/radsan_interceptors.h b/compiler-rt/lib/radsan/radsan_interceptors.h index 6ce3943b40131..9f020fa9d4df5 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.h +++ b/compiler-rt/lib/radsan/radsan_interceptors.h @@ -1,10 +1,13 @@ -/** - This file is part of the RealtimeSanitizer (RADSan) project. - https://github.com/realtime-sanitizer/radsan - - Copyright 2023 David Trevelyan & Alistair Barker - Subject to GNU General Public License (GPL) v3.0 -*/ +//===--- radsan_interceptors.h - Realtime Sanitizer --------------*- C++ +//-*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// #pragma once diff --git a/compiler-rt/lib/radsan/radsan_preinit.cpp b/compiler-rt/lib/radsan/radsan_preinit.cpp index f130dadb92e4b..221a076d3e8a9 100644 --- a/compiler-rt/lib/radsan/radsan_preinit.cpp +++ b/compiler-rt/lib/radsan/radsan_preinit.cpp @@ -15,7 +15,7 @@ // exported. // This code is linked into the main executable when -fsanitize=realtime is in // the link flags. It can only use exported interface functions. -__attribute__((section(".preinit_array"), used)) -void (*__local_radsan_preinit)(void) = radsan_init; +__attribute__((section(".preinit_array"), + used)) void (*__local_radsan_preinit)(void) = radsan_init; #endif diff --git a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp index 8b429b946947a..d389b60e8cd90 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp @@ -1,10 +1,13 @@ -/** - This file is part of the RealtimeSanitizer (RADSan) project. - https://github.com/realtime-sanitizer/radsan - - Copyright 2023 David Trevelyan & Alistair Barker - Subject to GNU General Public License (GPL) v3.0 -*/ +//===--- radsan_test_context.cpp - Realtime Sanitizer --------------*- C++ +//-*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// #include "radsan_test_utilities.h" diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp index 00a6153f3ccdd..074f3c9aab012 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp @@ -1,10 +1,13 @@ -/** - This file is part of the RealtimeSanitizer (RADSan) project. - https://github.com/realtime-sanitizer/radsan - - Copyright 2023 David Trevelyan & Alistair Barker - Subject to GNU General Public License (GPL) v3.0 -*/ +//===--- radsan_test_interceptors.cpp - Realtime Sanitizer --------------*- C++ +//-*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// #include "gtest/gtest.h" @@ -222,7 +225,7 @@ TEST(TestRadsanInterceptors, CloseDiesWhenRealtime) { TEST(TestRadsanInterceptors, FopenDiesWhenRealtime) { auto Func = []() { - FILE* Fd = fopen(TemporaryFilePath(), "w"); + FILE *Fd = fopen(TemporaryFilePath(), "w"); EXPECT_THAT(Fd, Ne(nullptr)); }; ExpectRealtimeDeath(Func, "fopen"); @@ -231,7 +234,7 @@ TEST(TestRadsanInterceptors, FopenDiesWhenRealtime) { } TEST(TestRadsanInterceptors, FreadDiesWhenRealtime) { - FILE* Fd = fopen(TemporaryFilePath(), "w"); + FILE *Fd = fopen(TemporaryFilePath(), "w"); auto Func = [Fd]() { char c{}; fread(&c, 1, 1, Fd); @@ -244,9 +247,9 @@ TEST(TestRadsanInterceptors, FreadDiesWhenRealtime) { } TEST(TestRadsanInterceptors, FwriteDiesWhenRealtime) { - FILE* Fd = fopen(TemporaryFilePath(), "w"); + FILE *Fd = fopen(TemporaryFilePath(), "w"); ASSERT_NE(nullptr, Fd); - const char* Message = "Hello, world!"; + const char *Message = "Hello, world!"; auto Func = [&]() { fwrite(&Message, 1, 4, Fd); }; ExpectRealtimeDeath(Func, "fwrite"); ExpectNonRealtimeSurvival(Func); @@ -254,7 +257,7 @@ TEST(TestRadsanInterceptors, FwriteDiesWhenRealtime) { } TEST(TestRadsanInterceptors, FcloseDiesWhenRealtime) { - FILE* Fd = fopen(TemporaryFilePath(), "w"); + FILE *Fd = fopen(TemporaryFilePath(), "w"); EXPECT_THAT(Fd, Ne(nullptr)); auto Func = [Fd]() { fclose(Fd); }; ExpectRealtimeDeath(Func, "fclose"); @@ -269,7 +272,7 @@ TEST(TestRadsanInterceptors, PutsDiesWhenRealtime) { } TEST(TestRadsanInterceptors, FputsDiesWhenRealtime) { - FILE* Fd = fopen(TemporaryFilePath(), "w"); + FILE *Fd = fopen(TemporaryFilePath(), "w"); ASSERT_THAT(Fd, Ne(nullptr)) << errno; auto Func = [Fd]() { fputs("Hello, world!\n", Fd); }; ExpectRealtimeDeath(Func); diff --git a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h index 1c1d8908fa92a..f8e5e0be0a7cd 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h +++ b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h @@ -1,20 +1,23 @@ -/** - This file is part of the RealtimeSanitizer (RADSan) project. - https://github.com/realtime-sanitizer/radsan - - Copyright 2023 David Trevelyan & Alistair Barker - Subject to GNU General Public License (GPL) v3.0 -*/ +//===--- radsan_test_utilities.h - Realtime Sanitizer --------------*- C++ +//-*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// #pragma once +#include "radsan.h" #include "gmock/gmock.h" #include namespace radsan_testing { -template -[[clang::realtime]] void RealtimeInvoke(Function &&Func) { +template [[clang::realtime]] void RealtimeInvoke(Function &&Func) { std::forward(Func)(); } From 77ee4a8886e25bb4b9b0f9064c18c287087e3ecd Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Sun, 19 May 2024 22:12:18 -0700 Subject: [PATCH 17/47] PR: Delete python header comment --- compiler-rt/test/radsan/lit.cfg.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler-rt/test/radsan/lit.cfg.py b/compiler-rt/test/radsan/lit.cfg.py index 32af62dfb8e04..b9e4dbc03abb6 100644 --- a/compiler-rt/test/radsan/lit.cfg.py +++ b/compiler-rt/test/radsan/lit.cfg.py @@ -1,5 +1,3 @@ -# -*- Python -*- - import os # Setup config name. From d7861684bf3efc94c5c5c3f2170d951e4745c5bc Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Sun, 19 May 2024 22:28:39 -0700 Subject: [PATCH 18/47] PR: Change main namespace name to __radsan --- compiler-rt/lib/radsan/radsan.cpp | 10 +- compiler-rt/lib/radsan/radsan_context.cpp | 8 +- compiler-rt/lib/radsan/radsan_context.h | 4 +- .../lib/radsan/radsan_interceptors.cpp | 100 +++++++++--------- compiler-rt/lib/radsan/radsan_interceptors.h | 2 +- compiler-rt/lib/radsan/radsan_stack.cpp | 7 +- compiler-rt/lib/radsan/radsan_stack.h | 2 +- .../lib/radsan/tests/radsan_test_context.cpp | 14 +-- 8 files changed, 73 insertions(+), 74 deletions(-) diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp index 9d5c96a9b07b5..c0d481a9e327e 100644 --- a/compiler-rt/lib/radsan/radsan.cpp +++ b/compiler-rt/lib/radsan/radsan.cpp @@ -13,23 +13,23 @@ extern "C" { SANITIZER_INTERFACE_ATTRIBUTE void radsan_init() { - radsan::InitializeInterceptors(); + __radsan::InitializeInterceptors(); } SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter() { - radsan::GetContextForThisThread().RealtimePush(); + __radsan::GetContextForThisThread().RealtimePush(); } SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_exit() { - radsan::GetContextForThisThread().RealtimePop(); + __radsan::GetContextForThisThread().RealtimePop(); } SANITIZER_INTERFACE_ATTRIBUTE void radsan_off() { - radsan::GetContextForThisThread().BypassPush(); + __radsan::GetContextForThisThread().BypassPush(); } SANITIZER_INTERFACE_ATTRIBUTE void radsan_on() { - radsan::GetContextForThisThread().BypassPop(); + __radsan::GetContextForThisThread().BypassPop(); } } // extern "C" diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp index 21b082c524774..c3204848a4160 100644 --- a/compiler-rt/lib/radsan/radsan_context.cpp +++ b/compiler-rt/lib/radsan/radsan_context.cpp @@ -26,7 +26,7 @@ static pthread_key_t Key; static pthread_once_t KeyOnce = PTHREAD_ONCE_INIT; void internalFree(void *Ptr) { __sanitizer::InternalFree(Ptr); } -using radsan::Context; +using __radsan::Context; Context &GetContextForThisThreadImpl() { auto MakeTlsKey = []() { @@ -64,7 +64,7 @@ void InvokeViolationDetectedAction() { exit(EXIT_FAILURE); } } // namespace detail -namespace radsan { +namespace __radsan { Context::Context() = default; @@ -94,11 +94,11 @@ void Context::PrintDiagnostics(const char *InterceptedFunctionName) { "Real-time violation: intercepted call to real-time unsafe function " "`%s` in real-time context! Stack trace:\n", InterceptedFunctionName); - radsan::PrintStackTrace(); + __radsan::PrintStackTrace(); } Context &GetContextForThisThread() { return detail::GetContextForThisThreadImpl(); } -} // namespace radsan +} // namespace __radsan diff --git a/compiler-rt/lib/radsan/radsan_context.h b/compiler-rt/lib/radsan/radsan_context.h index 5b874e74b8317..e0c515d790a87 100644 --- a/compiler-rt/lib/radsan/radsan_context.h +++ b/compiler-rt/lib/radsan/radsan_context.h @@ -8,7 +8,7 @@ #pragma once -namespace radsan { +namespace __radsan { class Context { public: @@ -33,4 +33,4 @@ class Context { Context &GetContextForThisThread(); -} // namespace radsan +} // namespace __radsan diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp index 57ac631060c4f..55b1a9b93d1aa 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.cpp +++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp @@ -40,11 +40,11 @@ using namespace __sanitizer; -namespace radsan { +namespace __radsan { void ExpectNotRealtime(const char *InterceptedFunctionName) { GetContextForThisThread().ExpectNotRealtime(InterceptedFunctionName); } -} // namespace radsan +} // namespace __radsan /* Filesystem @@ -53,7 +53,7 @@ void ExpectNotRealtime(const char *InterceptedFunctionName) { INTERCEPTOR(int, open, const char *path, int oflag, ...) { // TODO Establish whether we should intercept here if the flag contains // O_NONBLOCK - radsan::ExpectNotRealtime("open"); + __radsan::ExpectNotRealtime("open"); va_list args; va_start(args, oflag); const mode_t mode = va_arg(args, int); @@ -66,7 +66,7 @@ INTERCEPTOR(int, open, const char *path, int oflag, ...) { INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) { // TODO Establish whether we should intercept here if the flag contains // O_NONBLOCK - radsan::ExpectNotRealtime("openat"); + __radsan::ExpectNotRealtime("openat"); va_list args; va_start(args, oflag); mode_t mode = va_arg(args, int); @@ -79,13 +79,13 @@ INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) { INTERCEPTOR(int, creat, const char *path, mode_t mode) { // TODO Establish whether we should intercept here if the flag contains // O_NONBLOCK - radsan::ExpectNotRealtime("creat"); + __radsan::ExpectNotRealtime("creat"); auto result = REAL(creat)(path, mode); return result; } INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) { - radsan::ExpectNotRealtime("fcntl"); + __radsan::ExpectNotRealtime("fcntl"); va_list args; va_start(args, cmd); @@ -105,34 +105,34 @@ INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) { } INTERCEPTOR(int, close, int filedes) { - radsan::ExpectNotRealtime("close"); + __radsan::ExpectNotRealtime("close"); return REAL(close)(filedes); } INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) { - radsan::ExpectNotRealtime("fopen"); + __radsan::ExpectNotRealtime("fopen"); return REAL(fopen)(path, mode); } INTERCEPTOR(size_t, fread, void *ptr, size_t size, size_t nitems, FILE *stream) { - radsan::ExpectNotRealtime("fread"); + __radsan::ExpectNotRealtime("fread"); return REAL(fread)(ptr, size, nitems, stream); } INTERCEPTOR(size_t, fwrite, const void *ptr, size_t size, size_t nitems, FILE *stream) { - radsan::ExpectNotRealtime("fwrite"); + __radsan::ExpectNotRealtime("fwrite"); return REAL(fwrite)(ptr, size, nitems, stream); } INTERCEPTOR(int, fclose, FILE *stream) { - radsan::ExpectNotRealtime("fclose"); + __radsan::ExpectNotRealtime("fclose"); return REAL(fclose)(stream); } INTERCEPTOR(int, fputs, const char *s, FILE *stream) { - radsan::ExpectNotRealtime("fputs"); + __radsan::ExpectNotRealtime("fputs"); return REAL(fputs)(s, stream); } @@ -141,7 +141,7 @@ INTERCEPTOR(int, fputs, const char *s, FILE *stream) { */ INTERCEPTOR(int, puts, const char *s) { - radsan::ExpectNotRealtime("puts"); + __radsan::ExpectNotRealtime("puts"); return REAL(puts)(s); } @@ -154,77 +154,77 @@ INTERCEPTOR(int, puts, const char *s) { // OSSpinLockLock is deprecated, but still in use in libc++ #pragma clang diagnostic ignored "-Wdeprecated-declarations" INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) { - radsan::ExpectNotRealtime("OSSpinLockLock"); + __radsan::ExpectNotRealtime("OSSpinLockLock"); return REAL(OSSpinLockLock)(lock); } #pragma clang diagnostic pop INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) { - radsan::ExpectNotRealtime("os_unfair_lock_lock"); + __radsan::ExpectNotRealtime("os_unfair_lock_lock"); return REAL(os_unfair_lock_lock)(lock); } #elif SANITIZER_LINUX INTERCEPTOR(int, pthread_spin_lock, pthread_spinlock_t *spinlock) { - radsan::ExpectNotRealtime("pthread_spin_lock"); + __radsan::ExpectNotRealtime("pthread_spin_lock"); return REAL(pthread_spin_lock)(spinlock); } #endif INTERCEPTOR(int, pthread_create, pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { - radsan::ExpectNotRealtime("pthread_create"); + __radsan::ExpectNotRealtime("pthread_create"); return REAL(pthread_create)(thread, attr, start_routine, arg); } INTERCEPTOR(int, pthread_mutex_lock, pthread_mutex_t *mutex) { - radsan::ExpectNotRealtime("pthread_mutex_lock"); + __radsan::ExpectNotRealtime("pthread_mutex_lock"); return REAL(pthread_mutex_lock)(mutex); } INTERCEPTOR(int, pthread_mutex_unlock, pthread_mutex_t *mutex) { - radsan::ExpectNotRealtime("pthread_mutex_unlock"); + __radsan::ExpectNotRealtime("pthread_mutex_unlock"); return REAL(pthread_mutex_unlock)(mutex); } INTERCEPTOR(int, pthread_join, pthread_t thread, void **value_ptr) { - radsan::ExpectNotRealtime("pthread_join"); + __radsan::ExpectNotRealtime("pthread_join"); return REAL(pthread_join)(thread, value_ptr); } INTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *cond) { - radsan::ExpectNotRealtime("pthread_cond_signal"); + __radsan::ExpectNotRealtime("pthread_cond_signal"); return REAL(pthread_cond_signal)(cond); } INTERCEPTOR(int, pthread_cond_broadcast, pthread_cond_t *cond) { - radsan::ExpectNotRealtime("pthread_cond_broadcast"); + __radsan::ExpectNotRealtime("pthread_cond_broadcast"); return REAL(pthread_cond_broadcast)(cond); } INTERCEPTOR(int, pthread_cond_wait, pthread_cond_t *cond, pthread_mutex_t *mutex) { - radsan::ExpectNotRealtime("pthread_cond_wait"); + __radsan::ExpectNotRealtime("pthread_cond_wait"); return REAL(pthread_cond_wait)(cond, mutex); } INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *cond, pthread_mutex_t *mutex, const timespec *ts) { - radsan::ExpectNotRealtime("pthread_cond_timedwait"); + __radsan::ExpectNotRealtime("pthread_cond_timedwait"); return REAL(pthread_cond_timedwait)(cond, mutex, ts); } INTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *lock) { - radsan::ExpectNotRealtime("pthread_rwlock_rdlock"); + __radsan::ExpectNotRealtime("pthread_rwlock_rdlock"); return REAL(pthread_rwlock_rdlock)(lock); } INTERCEPTOR(int, pthread_rwlock_unlock, pthread_rwlock_t *lock) { - radsan::ExpectNotRealtime("pthread_rwlock_unlock"); + __radsan::ExpectNotRealtime("pthread_rwlock_unlock"); return REAL(pthread_rwlock_unlock)(lock); } INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) { - radsan::ExpectNotRealtime("pthread_rwlock_wrlock"); + __radsan::ExpectNotRealtime("pthread_rwlock_wrlock"); return REAL(pthread_rwlock_wrlock)(lock); } @@ -233,18 +233,18 @@ INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) { */ INTERCEPTOR(unsigned int, sleep, unsigned int s) { - radsan::ExpectNotRealtime("sleep"); + __radsan::ExpectNotRealtime("sleep"); return REAL(sleep)(s); } INTERCEPTOR(int, usleep, useconds_t u) { - radsan::ExpectNotRealtime("usleep"); + __radsan::ExpectNotRealtime("usleep"); return REAL(usleep)(u); } INTERCEPTOR(int, nanosleep, const struct timespec *rqtp, struct timespec *rmtp) { - radsan::ExpectNotRealtime("nanosleep"); + __radsan::ExpectNotRealtime("nanosleep"); return REAL(nanosleep)(rqtp, rmtp); } @@ -253,40 +253,40 @@ INTERCEPTOR(int, nanosleep, const struct timespec *rqtp, */ INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) { - radsan::ExpectNotRealtime("calloc"); + __radsan::ExpectNotRealtime("calloc"); return REAL(calloc)(num, size); } INTERCEPTOR(void, free, void *ptr) { if (ptr != NULL) { - radsan::ExpectNotRealtime("free"); + __radsan::ExpectNotRealtime("free"); } return REAL(free)(ptr); } INTERCEPTOR(void *, malloc, SIZE_T size) { - radsan::ExpectNotRealtime("malloc"); + __radsan::ExpectNotRealtime("malloc"); return REAL(malloc)(size); } INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) { - radsan::ExpectNotRealtime("realloc"); + __radsan::ExpectNotRealtime("realloc"); return REAL(realloc)(ptr, size); } INTERCEPTOR(void *, reallocf, void *ptr, SIZE_T size) { - radsan::ExpectNotRealtime("reallocf"); + __radsan::ExpectNotRealtime("reallocf"); return REAL(reallocf)(ptr, size); } INTERCEPTOR(void *, valloc, SIZE_T size) { - radsan::ExpectNotRealtime("valloc"); + __radsan::ExpectNotRealtime("valloc"); return REAL(valloc)(size); } #if SANITIZER_INTERCEPT_ALIGNED_ALLOC INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) { - radsan::ExpectNotRealtime("aligned_alloc"); + __radsan::ExpectNotRealtime("aligned_alloc"); return REAL(aligned_alloc)(alignment, size); } #define RADSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc) @@ -295,20 +295,20 @@ INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) { #endif INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) { - radsan::ExpectNotRealtime("posix_memalign"); + __radsan::ExpectNotRealtime("posix_memalign"); return REAL(posix_memalign)(memptr, alignment, size); } #if SANITIZER_INTERCEPT_MEMALIGN INTERCEPTOR(void *, memalign, size_t alignment, size_t size) { - radsan::ExpectNotRealtime("memalign"); + __radsan::ExpectNotRealtime("memalign"); return REAL(memalign)(alignment, size); } #endif #if SANITIZER_INTERCEPT_PVALLOC INTERCEPTOR(void *, pvalloc, size_t size) { - radsan::ExpectNotRealtime("pvalloc"); + __radsan::ExpectNotRealtime("pvalloc"); return REAL(pvalloc)(size); } #endif @@ -318,45 +318,45 @@ INTERCEPTOR(void *, pvalloc, size_t size) { */ INTERCEPTOR(int, socket, int domain, int type, int protocol) { - radsan::ExpectNotRealtime("socket"); + __radsan::ExpectNotRealtime("socket"); return REAL(socket)(domain, type, protocol); } INTERCEPTOR(ssize_t, send, int sockfd, const void *buf, size_t len, int flags) { - radsan::ExpectNotRealtime("send"); + __radsan::ExpectNotRealtime("send"); return REAL(send)(sockfd, buf, len, flags); } INTERCEPTOR(ssize_t, sendmsg, int socket, const struct msghdr *message, int flags) { - radsan::ExpectNotRealtime("sendmsg"); + __radsan::ExpectNotRealtime("sendmsg"); return REAL(sendmsg)(socket, message, flags); } INTERCEPTOR(ssize_t, sendto, int socket, const void *buffer, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len) { - radsan::ExpectNotRealtime("sendto"); + __radsan::ExpectNotRealtime("sendto"); return REAL(sendto)(socket, buffer, length, flags, dest_addr, dest_len); } INTERCEPTOR(ssize_t, recv, int socket, void *buffer, size_t length, int flags) { - radsan::ExpectNotRealtime("recv"); + __radsan::ExpectNotRealtime("recv"); return REAL(recv)(socket, buffer, length, flags); } INTERCEPTOR(ssize_t, recvfrom, int socket, void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len) { - radsan::ExpectNotRealtime("recvfrom"); + __radsan::ExpectNotRealtime("recvfrom"); return REAL(recvfrom)(socket, buffer, length, flags, address, address_len); } INTERCEPTOR(ssize_t, recvmsg, int socket, struct msghdr *message, int flags) { - radsan::ExpectNotRealtime("recvmsg"); + __radsan::ExpectNotRealtime("recvmsg"); return REAL(recvmsg)(socket, message, flags); } INTERCEPTOR(int, shutdown, int socket, int how) { - radsan::ExpectNotRealtime("shutdown"); + __radsan::ExpectNotRealtime("shutdown"); return REAL(shutdown)(socket, how); } @@ -364,7 +364,7 @@ INTERCEPTOR(int, shutdown, int socket, int how) { Preinit */ -namespace radsan { +namespace __radsan { void InitializeInterceptors() { INTERCEPT_FUNCTION(calloc); INTERCEPT_FUNCTION(free); @@ -425,4 +425,4 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(recvfrom); INTERCEPT_FUNCTION(shutdown); } -} // namespace radsan +} // namespace __radsan diff --git a/compiler-rt/lib/radsan/radsan_interceptors.h b/compiler-rt/lib/radsan/radsan_interceptors.h index 9f020fa9d4df5..223d2afb93b10 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.h +++ b/compiler-rt/lib/radsan/radsan_interceptors.h @@ -11,6 +11,6 @@ #pragma once -namespace radsan { +namespace __radsan { void InitializeInterceptors(); } diff --git a/compiler-rt/lib/radsan/radsan_stack.cpp b/compiler-rt/lib/radsan/radsan_stack.cpp index 8330dbb4844b1..0ce23858da9ab 100644 --- a/compiler-rt/lib/radsan/radsan_stack.cpp +++ b/compiler-rt/lib/radsan/radsan_stack.cpp @@ -25,7 +25,8 @@ void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context, } } // namespace __sanitizer -namespace { +namespace __radsan { + void SetGlobalStackTraceFormat() { SetCommonFlagsDefaults(); CommonFlags cf; @@ -34,9 +35,7 @@ void SetGlobalStackTraceFormat() { cf.external_symbolizer_path = GetEnv("RADSAN_SYMBOLIZER_PATH"); OverrideCommonFlags(cf); } -} // namespace -namespace radsan { void PrintStackTrace() { BufferedStackTrace Stack{}; @@ -47,4 +46,4 @@ void PrintStackTrace() { SetGlobalStackTraceFormat(); Stack.Print(); } -} // namespace radsan +} // namespace __radsan diff --git a/compiler-rt/lib/radsan/radsan_stack.h b/compiler-rt/lib/radsan/radsan_stack.h index 28bb1bc932fc9..f30cabc88bf2e 100644 --- a/compiler-rt/lib/radsan/radsan_stack.h +++ b/compiler-rt/lib/radsan/radsan_stack.h @@ -8,6 +8,6 @@ #pragma once -namespace radsan { +namespace __radsan { void PrintStackTrace(); } diff --git a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp index d389b60e8cd90..69d788b37ba01 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp @@ -13,22 +13,22 @@ #include "radsan_context.h" -TEST(TestRadsanContext, CanCreateContext) { radsan::Context Context{}; } +TEST(TestRadsanContext, CanCreateContext) { __radsan::Context Context{}; } TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieBeforeRealtimePush) { - radsan::Context Context{}; + __radsan::Context Context{}; Context.ExpectNotRealtime("do_some_stuff"); } TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterPushAndPop) { - radsan::Context Context{}; + __radsan::Context Context{}; Context.RealtimePush(); Context.RealtimePop(); Context.ExpectNotRealtime("do_some_stuff"); } TEST(TestRadsanContext, ExpectNotRealtimeDiesAfterRealtimePush) { - radsan::Context Context{}; + __radsan::Context Context{}; Context.RealtimePush(); EXPECT_DEATH(Context.ExpectNotRealtime("do_some_stuff"), ""); @@ -36,7 +36,7 @@ TEST(TestRadsanContext, ExpectNotRealtimeDiesAfterRealtimePush) { TEST(TestRadsanContext, ExpectNotRealtimeDiesAfterRealtimeAfterMorePushesThanPops) { - radsan::Context Context{}; + __radsan::Context Context{}; Context.RealtimePush(); Context.RealtimePush(); @@ -47,7 +47,7 @@ TEST(TestRadsanContext, } TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) { - radsan::Context Context{}; + __radsan::Context Context{}; Context.RealtimePush(); Context.BypassPush(); @@ -56,7 +56,7 @@ TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) { TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieIfBypassDepthIsGreaterThanZero) { - radsan::Context Context{}; + __radsan::Context Context{}; Context.RealtimePush(); Context.BypassPush(); From ce7df2ee917998a40c924051734f1ea9014850e8 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Sun, 19 May 2024 22:31:49 -0700 Subject: [PATCH 19/47] PR: Fix stack trace namespace --- compiler-rt/lib/radsan/radsan_stack.cpp | 8 +++++--- compiler-rt/lib/radsan/radsan_stack.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler-rt/lib/radsan/radsan_stack.cpp b/compiler-rt/lib/radsan/radsan_stack.cpp index 0ce23858da9ab..afd22b7c1f58f 100644 --- a/compiler-rt/lib/radsan/radsan_stack.cpp +++ b/compiler-rt/lib/radsan/radsan_stack.cpp @@ -6,6 +6,8 @@ Subject to GNU General Public License (GPL) v3.0 */ +#include "radsan_stack.h" + #include #include @@ -26,7 +28,6 @@ void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context, } // namespace __sanitizer namespace __radsan { - void SetGlobalStackTraceFormat() { SetCommonFlagsDefaults(); CommonFlags cf; @@ -35,8 +36,10 @@ void SetGlobalStackTraceFormat() { cf.external_symbolizer_path = GetEnv("RADSAN_SYMBOLIZER_PATH"); OverrideCommonFlags(cf); } +} // namespace __radsan -void PrintStackTrace() { +using namespace __radsan; +void __radsan::PrintStackTrace() { BufferedStackTrace Stack{}; @@ -46,4 +49,3 @@ void PrintStackTrace() { SetGlobalStackTraceFormat(); Stack.Print(); } -} // namespace __radsan diff --git a/compiler-rt/lib/radsan/radsan_stack.h b/compiler-rt/lib/radsan/radsan_stack.h index f30cabc88bf2e..f200de35e8585 100644 --- a/compiler-rt/lib/radsan/radsan_stack.h +++ b/compiler-rt/lib/radsan/radsan_stack.h @@ -10,4 +10,4 @@ namespace __radsan { void PrintStackTrace(); -} +} // namespace __radsan From e784b87d05be134ddfa1d74f02e873f13475da43 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Sun, 19 May 2024 22:35:21 -0700 Subject: [PATCH 20/47] PR: Fix incorrect C++ style comments --- .../lib/radsan/radsan_interceptors.cpp | 32 ++++--------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp index 55b1a9b93d1aa..05de009ddd8ba 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.cpp +++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp @@ -46,9 +46,7 @@ void ExpectNotRealtime(const char *InterceptedFunctionName) { } } // namespace __radsan -/* - Filesystem -*/ +// Filesystem INTERCEPTOR(int, open, const char *path, int oflag, ...) { // TODO Establish whether we should intercept here if the flag contains @@ -136,19 +134,13 @@ INTERCEPTOR(int, fputs, const char *s, FILE *stream) { return REAL(fputs)(s, stream); } -/* - Streams -*/ - +// Streams INTERCEPTOR(int, puts, const char *s) { __radsan::ExpectNotRealtime("puts"); return REAL(puts)(s); } -/* - Concurrency -*/ - + // Concurrency #if SANITIZER_APPLE #pragma clang diagnostic push // OSSpinLockLock is deprecated, but still in use in libc++ @@ -228,9 +220,7 @@ INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) { return REAL(pthread_rwlock_wrlock)(lock); } -/* - Sleeping -*/ +// Sleeping INTERCEPTOR(unsigned int, sleep, unsigned int s) { __radsan::ExpectNotRealtime("sleep"); @@ -248,9 +238,7 @@ INTERCEPTOR(int, nanosleep, const struct timespec *rqtp, return REAL(nanosleep)(rqtp, rmtp); } -/* - Memory -*/ +// Memory INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) { __radsan::ExpectNotRealtime("calloc"); @@ -313,10 +301,7 @@ INTERCEPTOR(void *, pvalloc, size_t size) { } #endif -/* - Sockets -*/ - +// Sockets INTERCEPTOR(int, socket, int domain, int type, int protocol) { __radsan::ExpectNotRealtime("socket"); return REAL(socket)(domain, type, protocol); @@ -360,10 +345,7 @@ INTERCEPTOR(int, shutdown, int socket, int how) { return REAL(shutdown)(socket, how); } -/* - Preinit -*/ - +// Preinit namespace __radsan { void InitializeInterceptors() { INTERCEPT_FUNCTION(calloc); From 8c959900ec75f86b523f7be227759043e17cb105 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Sun, 19 May 2024 22:37:52 -0700 Subject: [PATCH 21/47] PR: Prefix external API with dunderscores --- compiler-rt/lib/radsan/radsan.cpp | 10 +++++----- compiler-rt/lib/radsan/radsan.h | 12 ++++++------ compiler-rt/lib/radsan/radsan_preinit.cpp | 2 +- .../lib/radsan/tests/radsan_test_functional.cpp | 4 ++-- compiler-rt/lib/radsan/tests/radsan_test_utilities.h | 4 +++- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp index c0d481a9e327e..3cd8eb067f939 100644 --- a/compiler-rt/lib/radsan/radsan.cpp +++ b/compiler-rt/lib/radsan/radsan.cpp @@ -12,23 +12,23 @@ extern "C" { -SANITIZER_INTERFACE_ATTRIBUTE void radsan_init() { +SANITIZER_INTERFACE_ATTRIBUTE void __radsan_init() { __radsan::InitializeInterceptors(); } -SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter() { +SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_enter() { __radsan::GetContextForThisThread().RealtimePush(); } -SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_exit() { +SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_exit() { __radsan::GetContextForThisThread().RealtimePop(); } -SANITIZER_INTERFACE_ATTRIBUTE void radsan_off() { +SANITIZER_INTERFACE_ATTRIBUTE void __radsan_off() { __radsan::GetContextForThisThread().BypassPush(); } -SANITIZER_INTERFACE_ATTRIBUTE void radsan_on() { +SANITIZER_INTERFACE_ATTRIBUTE void __radsan_on() { __radsan::GetContextForThisThread().BypassPop(); } diff --git a/compiler-rt/lib/radsan/radsan.h b/compiler-rt/lib/radsan/radsan.h index f8e248f8938d8..d8bfc13c22c25 100644 --- a/compiler-rt/lib/radsan/radsan.h +++ b/compiler-rt/lib/radsan/radsan.h @@ -16,7 +16,7 @@ extern "C" { A call to this method is added to the preinit array on Linux systems. */ -SANITIZER_INTERFACE_ATTRIBUTE void radsan_init(); +SANITIZER_INTERFACE_ATTRIBUTE void __radsan_init(); /** Enter real-time context. @@ -24,25 +24,25 @@ SANITIZER_INTERFACE_ATTRIBUTE void radsan_init(); violations are detected. Calls to this method are injected at the code generation stage when RADSan is enabled. */ -SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_enter(); +SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_enter(); /** Exit the real-time context. When not in a real-time context, RADSan interceptors will simply forward intercepted method calls to the real methods. */ -SANITIZER_INTERFACE_ATTRIBUTE void radsan_realtime_exit(); +SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_exit(); /** Disable all RADSan error reporting. Injected into the code if "nosanitize(realtime)" is on a function. */ -SANITIZER_INTERFACE_ATTRIBUTE void radsan_off(); +SANITIZER_INTERFACE_ATTRIBUTE void __radsan_off(); /** Re-enable all RADSan error reporting. - The counterpart to `radsan_off`. + The counterpart to `__radsan_off`. */ -SANITIZER_INTERFACE_ATTRIBUTE void radsan_on(); +SANITIZER_INTERFACE_ATTRIBUTE void __radsan_on(); } // extern "C" diff --git a/compiler-rt/lib/radsan/radsan_preinit.cpp b/compiler-rt/lib/radsan/radsan_preinit.cpp index 221a076d3e8a9..67be408156c03 100644 --- a/compiler-rt/lib/radsan/radsan_preinit.cpp +++ b/compiler-rt/lib/radsan/radsan_preinit.cpp @@ -16,6 +16,6 @@ // This code is linked into the main executable when -fsanitize=realtime is in // the link flags. It can only use exported interface functions. __attribute__((section(".preinit_array"), - used)) void (*__local_radsan_preinit)(void) = radsan_init; + used)) void (*__local_radsan_preinit)(void) = __radsan_init; #endif diff --git a/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp b/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp index ed02e1e32cd2d..897745876880d 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp @@ -198,10 +198,10 @@ TEST(TestRadsan, throwingAnExceptionDiesWhenRealtime) { TEST(TestRadsan, doesNotDieIfTurnedOff) { auto mutex = std::mutex{}; auto realtime_unsafe_func = [&]() { - radsan_off(); + __radsan_off(); mutex.lock(); mutex.unlock(); - radsan_on(); + __radsan_on(); }; RealtimeInvoke(realtime_unsafe_func); } diff --git a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h index f8e5e0be0a7cd..61d55ac5c9658 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h +++ b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h @@ -17,8 +17,10 @@ namespace radsan_testing { -template [[clang::realtime]] void RealtimeInvoke(Function &&Func) { +template void RealtimeInvoke(Function &&Func) { + __radsan_realtime_enter(); std::forward(Func)(); + __radsan_realtime_exit(); } template From ec71e552d63a5750752d71ea9464f6ad49fe807d Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Mon, 20 May 2024 08:39:46 -0700 Subject: [PATCH 22/47] PR: Fix variable naming cases for variables, leave lambdas for now --- compiler-rt/lib/radsan/radsan_context.cpp | 46 +++---- compiler-rt/lib/radsan/radsan_context.h | 8 +- .../lib/radsan/radsan_interceptors.cpp | 4 +- compiler-rt/lib/radsan/radsan_interceptors.h | 2 +- compiler-rt/lib/radsan/radsan_stack.cpp | 6 +- .../lib/radsan/tests/radsan_test_context.cpp | 62 ++++----- .../radsan/tests/radsan_test_functional.cpp | 116 ++++++++-------- .../radsan/tests/radsan_test_interceptors.cpp | 126 +++++++++--------- .../lib/radsan/tests/radsan_test_utilities.h | 4 +- 9 files changed, 187 insertions(+), 187 deletions(-) diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp index c3204848a4160..bc1ab4d0369cc 100644 --- a/compiler-rt/lib/radsan/radsan_context.cpp +++ b/compiler-rt/lib/radsan/radsan_context.cpp @@ -22,28 +22,28 @@ using namespace __sanitizer; namespace detail { -static pthread_key_t Key; -static pthread_once_t KeyOnce = PTHREAD_ONCE_INIT; -void internalFree(void *Ptr) { __sanitizer::InternalFree(Ptr); } +static pthread_key_t key; +static pthread_once_t key_once = PTHREAD_ONCE_INIT; +void internalFree(void *ptr) { __sanitizer::InternalFree(ptr); } using __radsan::Context; Context &GetContextForThisThreadImpl() { - auto MakeTlsKey = []() { - CHECK_EQ(pthread_key_create(&detail::Key, detail::internalFree), 0); + auto make_tls_key = []() { + CHECK_EQ(pthread_key_create(&detail::key, detail::internalFree), 0); }; - pthread_once(&detail::KeyOnce, MakeTlsKey); - Context *CurrentThreadContext = - static_cast(pthread_getspecific(detail::Key)); - if (CurrentThreadContext == nullptr) { - CurrentThreadContext = + pthread_once(&detail::key_once, make_tls_key); + Context *current_thread_context = + static_cast(pthread_getspecific(detail::key)); + if (current_thread_context == nullptr) { + current_thread_context = static_cast(InternalAlloc(sizeof(Context))); - new (CurrentThreadContext) Context(); - pthread_setspecific(detail::Key, CurrentThreadContext); + new (current_thread_context) Context(); + pthread_setspecific(detail::key, current_thread_context); } - return *CurrentThreadContext; + return *current_thread_context; } /* @@ -68,32 +68,32 @@ namespace __radsan { Context::Context() = default; -void Context::RealtimePush() { RealtimeDepth++; } +void Context::RealtimePush() { realtime_depth++; } -void Context::RealtimePop() { RealtimeDepth--; } +void Context::RealtimePop() { realtime_depth--; } -void Context::BypassPush() { BypassDepth++; } +void Context::BypassPush() { bypass_depth++; } -void Context::BypassPop() { BypassDepth--; } +void Context::BypassPop() { bypass_depth--; } -void Context::ExpectNotRealtime(const char *InterceptedFunctionName) { +void Context::ExpectNotRealtime(const char *intercepted_function_name) { if (InRealtimeContext() && !IsBypassed()) { BypassPush(); - PrintDiagnostics(InterceptedFunctionName); + PrintDiagnostics(intercepted_function_name); detail::InvokeViolationDetectedAction(); BypassPop(); } } -bool Context::InRealtimeContext() const { return RealtimeDepth > 0; } +bool Context::InRealtimeContext() const { return realtime_depth > 0; } -bool Context::IsBypassed() const { return BypassDepth > 0; } +bool Context::IsBypassed() const { return bypass_depth > 0; } -void Context::PrintDiagnostics(const char *InterceptedFunctionName) { +void Context::PrintDiagnostics(const char *intercepted_function_name) { fprintf(stderr, "Real-time violation: intercepted call to real-time unsafe function " "`%s` in real-time context! Stack trace:\n", - InterceptedFunctionName); + intercepted_function_name); __radsan::PrintStackTrace(); } diff --git a/compiler-rt/lib/radsan/radsan_context.h b/compiler-rt/lib/radsan/radsan_context.h index e0c515d790a87..1e4f9d314ca1a 100644 --- a/compiler-rt/lib/radsan/radsan_context.h +++ b/compiler-rt/lib/radsan/radsan_context.h @@ -20,15 +20,15 @@ class Context { void BypassPush(); void BypassPop(); - void ExpectNotRealtime(const char *InterceptedFunctionName); + void ExpectNotRealtime(const char *intercepted_function_name); private: bool InRealtimeContext() const; bool IsBypassed() const; - void PrintDiagnostics(const char *InterceptedFunctionName); + void PrintDiagnostics(const char *intercepted_function_name); - int RealtimeDepth{0}; - int BypassDepth{0}; + int realtime_depth{0}; + int bypass_depth{0}; }; Context &GetContextForThisThread(); diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp index 05de009ddd8ba..0816da4a113c1 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.cpp +++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp @@ -41,8 +41,8 @@ using namespace __sanitizer; namespace __radsan { -void ExpectNotRealtime(const char *InterceptedFunctionName) { - GetContextForThisThread().ExpectNotRealtime(InterceptedFunctionName); +void ExpectNotRealtime(const char *intercepted_function_name) { + GetContextForThisThread().ExpectNotRealtime(intercepted_function_name); } } // namespace __radsan diff --git a/compiler-rt/lib/radsan/radsan_interceptors.h b/compiler-rt/lib/radsan/radsan_interceptors.h index 223d2afb93b10..95dd44ca5bc80 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.h +++ b/compiler-rt/lib/radsan/radsan_interceptors.h @@ -13,4 +13,4 @@ namespace __radsan { void InitializeInterceptors(); -} +} // namespace __radsan diff --git a/compiler-rt/lib/radsan/radsan_stack.cpp b/compiler-rt/lib/radsan/radsan_stack.cpp index afd22b7c1f58f..eb941869397e6 100644 --- a/compiler-rt/lib/radsan/radsan_stack.cpp +++ b/compiler-rt/lib/radsan/radsan_stack.cpp @@ -41,11 +41,11 @@ void SetGlobalStackTraceFormat() { using namespace __radsan; void __radsan::PrintStackTrace() { - BufferedStackTrace Stack{}; + BufferedStackTrace stack{}; GET_CURRENT_PC_BP; - Stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal); + stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal); SetGlobalStackTraceFormat(); - Stack.Print(); + stack.Print(); } diff --git a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp index 69d788b37ba01..1c098fcabd2ad 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_context.cpp @@ -13,58 +13,58 @@ #include "radsan_context.h" -TEST(TestRadsanContext, CanCreateContext) { __radsan::Context Context{}; } +TEST(TestRadsanContext, CanCreateContext) { __radsan::Context context{}; } TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieBeforeRealtimePush) { - __radsan::Context Context{}; - Context.ExpectNotRealtime("do_some_stuff"); + __radsan::Context context{}; + context.ExpectNotRealtime("do_some_stuff"); } TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterPushAndPop) { - __radsan::Context Context{}; - Context.RealtimePush(); - Context.RealtimePop(); - Context.ExpectNotRealtime("do_some_stuff"); + __radsan::Context context{}; + context.RealtimePush(); + context.RealtimePop(); + context.ExpectNotRealtime("do_some_stuff"); } TEST(TestRadsanContext, ExpectNotRealtimeDiesAfterRealtimePush) { - __radsan::Context Context{}; + __radsan::Context context{}; - Context.RealtimePush(); - EXPECT_DEATH(Context.ExpectNotRealtime("do_some_stuff"), ""); + context.RealtimePush(); + EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), ""); } TEST(TestRadsanContext, ExpectNotRealtimeDiesAfterRealtimeAfterMorePushesThanPops) { - __radsan::Context Context{}; + __radsan::Context context{}; - Context.RealtimePush(); - Context.RealtimePush(); - Context.RealtimePush(); - Context.RealtimePop(); - Context.RealtimePop(); - EXPECT_DEATH(Context.ExpectNotRealtime("do_some_stuff"), ""); + context.RealtimePush(); + context.RealtimePush(); + context.RealtimePush(); + context.RealtimePop(); + context.RealtimePop(); + EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), ""); } TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) { - __radsan::Context Context{}; + __radsan::Context context{}; - Context.RealtimePush(); - Context.BypassPush(); - Context.ExpectNotRealtime("do_some_stuff"); + context.RealtimePush(); + context.BypassPush(); + context.ExpectNotRealtime("do_some_stuff"); } TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieIfBypassDepthIsGreaterThanZero) { - __radsan::Context Context{}; + __radsan::Context context{}; - Context.RealtimePush(); - Context.BypassPush(); - Context.BypassPush(); - Context.BypassPush(); - Context.BypassPop(); - Context.BypassPop(); - Context.ExpectNotRealtime("do_some_stuff"); - Context.BypassPop(); - EXPECT_DEATH(Context.ExpectNotRealtime("do_some_stuff"), ""); + context.RealtimePush(); + context.BypassPush(); + context.BypassPush(); + context.BypassPush(); + context.BypassPop(); + context.BypassPop(); + context.ExpectNotRealtime("do_some_stuff"); + context.BypassPop(); + EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), ""); } diff --git a/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp b/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp index 897745876880d..7c5e85bc45768 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp @@ -40,26 +40,22 @@ using namespace testing; using namespace radsan_testing; using namespace std::chrono_literals; -namespace { -void invokeStdFunction(std::function &&function) { function(); } -} // namespace - -TEST(TestRadsan, vectorPushBackAllocationDiesWhenRealtime) { - auto vec = std::vector{}; - auto func = [&vec]() { vec.push_back(0.4f); }; - expectRealtimeDeath(func); +TEST(TestRadsan, VectorPushBackAllocationDiesWhenRealtime) { + std::vector vec{}; + auto Func = [&vec]() { vec.push_back(0.4f); }; + ExpectRealtimeDeath(Func); ASSERT_EQ(0u, vec.size()); - expectNonrealtimeSurvival(func); + ExpectNonRealtimeSurvival(Func); ASSERT_EQ(1u, vec.size()); } -TEST(TestRadsan, destructionOfObjectOnHeapDiesWhenRealtime) { - auto obj = std::make_unique>(); - auto func = [&obj]() { obj.reset(); }; - expectRealtimeDeath(func); - ASSERT_NE(nullptr, obj.get()); - expectNonrealtimeSurvival(func); - ASSERT_EQ(nullptr, obj.get()); +TEST(TestRadsan, DestructionOfObjectOnHeapDiesWhenRealtime) { + auto allocated_ptr = std::make_unique>(); + auto Func = [&allocated_ptr]() { allocated_ptr.reset(); }; + ExpectRealtimeDeath(Func); + ASSERT_NE(nullptr, allocated_ptr.get()); + ExpectNonRealtimeSurvival(Func); + ASSERT_EQ(nullptr, allocated_ptr.get()); } TEST(TestRadsan, sleepingAThreadDiesWhenRealtime) { @@ -82,51 +78,51 @@ TEST(TestRadsan, ofstreamCreationDiesWhenRealtime) { std::remove("./file.txt"); } -TEST(TestRadsan, lockingAMutexDiesWhenRealtime) { - auto mutex = std::mutex{}; - auto func = [&]() { mutex.lock(); }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); +TEST(TestRadsan, LockingAMutexDiesWhenRealtime) { + std::mutex mutex{}; + auto Func = [&]() { mutex.lock(); }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, unlockingAMutexDiesWhenRealtime) { - auto mutex = std::mutex{}; +TEST(TestRadsan, UnlockingAMutexDiesWhenRealtime) { + std::mutex mutex{}; mutex.lock(); - auto func = [&]() { mutex.unlock(); }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); + auto Func = [&]() { mutex.unlock(); }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); } #if RADSAN_TEST_SHARED_MUTEX -TEST(TestRadsan, lockingASharedMutexDiesWhenRealtime) { - auto mutex = std::shared_mutex(); - auto func = [&]() { mutex.lock(); }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); +TEST(TestRadsan, LockingASharedMutexDiesWhenRealtime) { + std::shared_mutex mutex{}; + auto Func = [&]() { mutex.lock(); }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, unlockingASharedMutexDiesWhenRealtime) { - auto mutex = std::shared_mutex(); +TEST(TestRadsan, UnlockingASharedMutexDiesWhenRealtime) { + std::shared_mutex mutex{}; mutex.lock(); - auto func = [&]() { mutex.unlock(); }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); + auto Func = [&]() { mutex.unlock(); }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, sharedLockingASharedMutexDiesWhenRealtime) { - auto mutex = std::shared_mutex(); - auto func = [&]() { mutex.lock_shared(); }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); +TEST(TestRadsan, SharedLockingASharedMutexDiesWhenRealtime) { + std::shared_mutex mutex{}; + auto Func = [&]() { mutex.lock_shared(); }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, sharedUnlockingASharedMutexDiesWhenRealtime) { - auto mutex = std::shared_mutex(); +TEST(TestRadsan, SharedUnlockingASharedMutexDiesWhenRealtime) { + std::shared_mutex mutex{}; mutex.lock_shared(); - auto func = [&]() { mutex.unlock_shared(); }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); + auto Func = [&]() { mutex.unlock_shared(); }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); } #endif // RADSAN_TEST_SHARED_MUTEX @@ -140,8 +136,12 @@ TEST(TestRadsan, launchingAThreadDiesWhenRealtime) { expectNonrealtimeSurvival(func); } -TEST(TestRadsan, copyingALambdaWithLargeCaptureDiesWhenRealtime) { - auto lots_of_data = std::array{}; +namespace { +void InvokeStdFunction(std::function &&function) { function(); } +} // namespace + +TEST(TestRadsan, CopyingALambdaWithLargeCaptureDiesWhenRealtime) { + std::array lots_of_data{}; auto lambda = [lots_of_data]() mutable { // Stop everything getting optimised out lots_of_data[3] = 0.25f; @@ -153,16 +153,16 @@ TEST(TestRadsan, copyingALambdaWithLargeCaptureDiesWhenRealtime) { expectNonrealtimeSurvival(func); } -TEST(TestRadsan, accessingALargeAtomicVariableDiesWhenRealtime) { - auto small_atomic = std::atomic{0.0f}; +TEST(TestRadsan, AccessingALargeAtomicVariableDiesWhenRealtime) { + std::atomic small_atomic{0.0f}; ASSERT_TRUE(small_atomic.is_lock_free()); - RealtimeInvoke([&small_atomic]() { auto x = small_atomic.load(); }); + RealtimeInvoke([&small_atomic]() { float x = small_atomic.load(); }); - auto large_atomic = std::atomic>{{}}; + std::atomic> large_atomic{}; ASSERT_FALSE(large_atomic.is_lock_free()); - auto func = [&]() { auto x = large_atomic.load(); }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); + auto Func = [&]() { auto x = large_atomic.load(); }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); } TEST(TestRadsan, firstCoutDiesWhenRealtime) { @@ -195,9 +195,9 @@ TEST(TestRadsan, throwingAnExceptionDiesWhenRealtime) { expectNonrealtimeSurvival(func); } -TEST(TestRadsan, doesNotDieIfTurnedOff) { - auto mutex = std::mutex{}; - auto realtime_unsafe_func = [&]() { +TEST(TestRadsan, DoesNotDieIfTurnedOff) { + std::mutex mutex{}; + auto RealtimeUnsafeFunc = [&]() { __radsan_off(); mutex.lock(); mutex.unlock(); diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp index 074f3c9aab012..353643559b82e 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp @@ -138,8 +138,8 @@ TEST(TestRadsanInterceptors, FreeSurvivesWhenRealtimeIfArgumentIsNull) { TEST(TestRadsanInterceptors, PosixMemalignDiesWhenRealtime) { auto Func = []() { - void *Mem; - posix_memalign(&Mem, 4, 4); + void *ptr; + posix_memalign(&ptr, 4, 4); }; expectRealtimeDeath(Func, "posix_memalign"); expectNonrealtimeSurvival(Func); @@ -225,8 +225,8 @@ TEST(TestRadsanInterceptors, CloseDiesWhenRealtime) { TEST(TestRadsanInterceptors, FopenDiesWhenRealtime) { auto Func = []() { - FILE *Fd = fopen(TemporaryFilePath(), "w"); - EXPECT_THAT(Fd, Ne(nullptr)); + FILE *fd = fopen(TemporaryFilePath(), "w"); + EXPECT_THAT(fd, Ne(nullptr)); }; ExpectRealtimeDeath(Func, "fopen"); ExpectNonRealtimeSurvival(Func); @@ -234,32 +234,32 @@ TEST(TestRadsanInterceptors, FopenDiesWhenRealtime) { } TEST(TestRadsanInterceptors, FreadDiesWhenRealtime) { - FILE *Fd = fopen(TemporaryFilePath(), "w"); - auto Func = [Fd]() { + FILE *fd = fopen(TemporaryFilePath(), "w"); + auto Func = [fd]() { char c{}; - fread(&c, 1, 1, Fd); + fread(&c, 1, 1, fd); }; ExpectRealtimeDeath(Func, "fread"); ExpectNonRealtimeSurvival(Func); - if (Fd != nullptr) - fclose(Fd); + if (fd != nullptr) + fclose(fd); std::remove(TemporaryFilePath()); } TEST(TestRadsanInterceptors, FwriteDiesWhenRealtime) { - FILE *Fd = fopen(TemporaryFilePath(), "w"); - ASSERT_NE(nullptr, Fd); - const char *Message = "Hello, world!"; - auto Func = [&]() { fwrite(&Message, 1, 4, Fd); }; + FILE *fd = fopen(TemporaryFilePath(), "w"); + ASSERT_NE(nullptr, fd); + const char *message = "Hello, world!"; + auto Func = [&]() { fwrite(&message, 1, 4, fd); }; ExpectRealtimeDeath(Func, "fwrite"); ExpectNonRealtimeSurvival(Func); std::remove(TemporaryFilePath()); } TEST(TestRadsanInterceptors, FcloseDiesWhenRealtime) { - FILE *Fd = fopen(TemporaryFilePath(), "w"); - EXPECT_THAT(Fd, Ne(nullptr)); - auto Func = [Fd]() { fclose(Fd); }; + FILE *fd = fopen(TemporaryFilePath(), "w"); + EXPECT_THAT(fd, Ne(nullptr)); + auto Func = [fd]() { fclose(fd); }; ExpectRealtimeDeath(Func, "fclose"); ExpectNonRealtimeSurvival(Func); std::remove(TemporaryFilePath()); @@ -272,13 +272,13 @@ TEST(TestRadsanInterceptors, PutsDiesWhenRealtime) { } TEST(TestRadsanInterceptors, FputsDiesWhenRealtime) { - FILE *Fd = fopen(TemporaryFilePath(), "w"); - ASSERT_THAT(Fd, Ne(nullptr)) << errno; - auto Func = [Fd]() { fputs("Hello, world!\n", Fd); }; + FILE *fd = fopen(TemporaryFilePath(), "w"); + ASSERT_THAT(fd, Ne(nullptr)) << errno; + auto Func = [fd]() { fputs("Hello, world!\n", fd); }; ExpectRealtimeDeath(Func); ExpectNonRealtimeSurvival(Func); - if (Fd != nullptr) - fclose(Fd); + if (fd != nullptr) + fclose(fd); std::remove(TemporaryFilePath()); } @@ -288,10 +288,10 @@ TEST(TestRadsanInterceptors, FputsDiesWhenRealtime) { TEST(TestRadsanInterceptors, PthreadCreateDiesWhenRealtime) { auto Func = []() { - pthread_t Thread{}; - const pthread_attr_t Attr{}; - struct thread_info *ThreadInfo; - pthread_create(&Thread, &Attr, &FakeThreadEntryPoint, ThreadInfo); + pthread_t thread{}; + const pthread_attr_t attr{}; + struct thread_info *thread_info; + pthread_create(&thread, &attr, &FakeThreadEntryPoint, thread_info); }; expectRealtimeDeath(Func, "pthread_create"); expectNonrealtimeSurvival(Func); @@ -299,8 +299,8 @@ TEST(TestRadsanInterceptors, PthreadCreateDiesWhenRealtime) { TEST(TestRadsanInterceptors, PthreadMutexLockDiesWhenRealtime) { auto Func = []() { - pthread_mutex_t Mutex{}; - pthread_mutex_lock(&Mutex); + pthread_mutex_t mutex{}; + pthread_mutex_lock(&mutex); }; expectRealtimeDeath(Func, "pthread_mutex_lock"); @@ -309,8 +309,8 @@ TEST(TestRadsanInterceptors, PthreadMutexLockDiesWhenRealtime) { TEST(TestRadsanInterceptors, PthreadMutexUnlockDiesWhenRealtime) { auto Func = []() { - pthread_mutex_t Mutex{}; - pthread_mutex_unlock(&Mutex); + pthread_mutex_t mutex{}; + pthread_mutex_unlock(&mutex); }; expectRealtimeDeath(Func, "pthread_mutex_unlock"); @@ -319,8 +319,8 @@ TEST(TestRadsanInterceptors, PthreadMutexUnlockDiesWhenRealtime) { TEST(TestRadsanInterceptors, PthreadMutexJoinDiesWhenRealtime) { auto Func = []() { - pthread_t Thread{}; - pthread_join(Thread, nullptr); + pthread_t thread{}; + pthread_join(thread, nullptr); }; expectRealtimeDeath(Func, "pthread_join"); @@ -334,8 +334,8 @@ TEST(TestRadsanInterceptors, PthreadMutexJoinDiesWhenRealtime) { #pragma clang diagnostic ignored "-Wdeprecated-declarations" TEST(TestRadsanInterceptors, OsSpinLockLockDiesWhenRealtime) { auto Func = []() { - OSSpinLock SpinLock{}; - OSSpinLockLock(&SpinLock); + OSSpinLock spin_lock{}; + OSSpinLockLock(&spin_lock); }; expectRealtimeDeath(Func, "OSSpinLockLock"); expectNonrealtimeSurvival(Func); @@ -344,8 +344,8 @@ TEST(TestRadsanInterceptors, OsSpinLockLockDiesWhenRealtime) { TEST(TestRadsanInterceptors, OsUnfairLockLockDiesWhenRealtime) { auto Func = []() { - os_unfair_lock_s UnfairLock{}; - os_unfair_lock_lock(&UnfairLock); + os_unfair_lock_s unfair_lock{}; + os_unfair_lock_lock(&unfair_lock); }; expectRealtimeDeath(Func, "os_unfair_lock_lock"); expectNonrealtimeSurvival(Func); @@ -354,9 +354,9 @@ TEST(TestRadsanInterceptors, OsUnfairLockLockDiesWhenRealtime) { #if SANITIZER_LINUX TEST(TestRadsanInterceptors, SpinLockLockDiesWhenRealtime) { - pthread_spinlock_t SpinLock; - pthread_spin_init(&SpinLock, PTHREAD_PROCESS_SHARED); - auto Func = [&]() { pthread_spin_lock(&SpinLock); }; + pthread_spinlock_t spin_lock; + pthread_spin_init(&spin_lock, PTHREAD_PROCESS_SHARED); + auto Func = [&]() { pthread_spin_lock(&spin_lock); }; expectRealtimeDeath(Func, "pthread_spin_lock"); expectNonrealtimeSurvival(Func); } @@ -364,8 +364,8 @@ TEST(TestRadsanInterceptors, SpinLockLockDiesWhenRealtime) { TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) { auto Func = []() { - pthread_cond_t Cond{}; - pthread_cond_signal(&Cond); + pthread_cond_t cond{}; + pthread_cond_signal(&cond); }; expectRealtimeDeath(Func, "pthread_cond_signal"); expectNonrealtimeSurvival(Func); @@ -373,19 +373,19 @@ TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) { TEST(TestRadsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) { auto Func = []() { - pthread_cond_t Cond; - pthread_cond_broadcast(&Cond); + pthread_cond_t cond; + pthread_cond_broadcast(&cond); }; expectRealtimeDeath(Func, "pthread_cond_broadcast"); expectNonrealtimeSurvival(Func); } TEST(TestRadsanInterceptors, PthreadCondWaitDiesWhenRealtime) { - pthread_cond_t Cond; - pthread_mutex_t Mutex; - ASSERT_EQ(0, pthread_cond_init(&Cond, nullptr)); - ASSERT_EQ(0, pthread_mutex_init(&Mutex, nullptr)); - auto Func = [&]() { pthread_cond_wait(&Cond, &Mutex); }; + pthread_cond_t cond; + pthread_mutex_t mutex; + ASSERT_EQ(0, pthread_cond_init(&cond, nullptr)); + ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr)); + auto Func = [&]() { pthread_cond_wait(&cond, &mutex); }; expectRealtimeDeath(Func, "pthread_cond_wait"); // It's very difficult to test the success case here without doing some // sleeping, which is at the mercy of the scheduler. What's really important @@ -394,8 +394,8 @@ TEST(TestRadsanInterceptors, PthreadCondWaitDiesWhenRealtime) { TEST(TestRadsanInterceptors, PthreadRwlockRdlockDiesWhenRealtime) { auto Func = []() { - pthread_rwlock_t RwLock; - pthread_rwlock_rdlock(&RwLock); + pthread_rwlock_t rw_lock; + pthread_rwlock_rdlock(&rw_lock); }; expectRealtimeDeath(Func, "pthread_rwlock_rdlock"); expectNonrealtimeSurvival(Func); @@ -403,8 +403,8 @@ TEST(TestRadsanInterceptors, PthreadRwlockRdlockDiesWhenRealtime) { TEST(TestRadsanInterceptors, PthreadRwlockUnlockDiesWhenRealtime) { auto Func = []() { - pthread_rwlock_t RwLock; - pthread_rwlock_unlock(&RwLock); + pthread_rwlock_t rw_lock; + pthread_rwlock_unlock(&rw_lock); }; expectRealtimeDeath(Func, "pthread_rwlock_unlock"); expectNonrealtimeSurvival(Func); @@ -412,8 +412,8 @@ TEST(TestRadsanInterceptors, PthreadRwlockUnlockDiesWhenRealtime) { TEST(TestRadsanInterceptors, PthreadRwlockWrlockDiesWhenRealtime) { auto Func = []() { - pthread_rwlock_t RwLock; - pthread_rwlock_wrlock(&RwLock); + pthread_rwlock_t rw_lock; + pthread_rwlock_wrlock(&rw_lock); }; expectRealtimeDeath(Func, "pthread_rwlock_wrlock"); expectNonrealtimeSurvival(Func); @@ -435,16 +435,16 @@ TEST(TestRadsanInterceptors, SendToASocketDiesWhenRealtime) { } TEST(TestRadsanInterceptors, SendmsgToASocketDiesWhenRealtime) { - msghdr Msg{}; - auto Func = [&]() { sendmsg(0, &Msg, 0); }; + msghdr msg{}; + auto Func = [&]() { sendmsg(0, &msg, 0); }; expectRealtimeDeath(Func, "sendmsg"); expectNonrealtimeSurvival(Func); } TEST(TestRadsanInterceptors, SendtoToASocketDiesWhenRealtime) { - sockaddr Addr{}; - socklen_t Len{}; - auto Func = [&]() { sendto(0, nullptr, 0, 0, &Addr, Len); }; + sockaddr addr{}; + socklen_t len{}; + auto Func = [&]() { sendto(0, nullptr, 0, 0, &addr, len); }; expectRealtimeDeath(Func, "sendto"); expectNonrealtimeSurvival(Func); } @@ -456,16 +456,16 @@ TEST(TestRadsanInterceptors, RecvFromASocketDiesWhenRealtime) { } TEST(TestRadsanInterceptors, RecvfromOnASocketDiesWhenRealtime) { - sockaddr Addr{}; - socklen_t Len{}; - auto Func = [&]() { recvfrom(0, nullptr, 0, 0, &Addr, &Len); }; + sockaddr addr{}; + socklen_t len{}; + auto Func = [&]() { recvfrom(0, nullptr, 0, 0, &addr, &len); }; expectRealtimeDeath(Func, "recvfrom"); expectNonrealtimeSurvival(Func); } TEST(TestRadsanInterceptors, RecvmsgOnASocketDiesWhenRealtime) { - msghdr Msg{}; - auto Func = [&]() { recvmsg(0, &Msg, 0); }; + msghdr msg{}; + auto Func = [&]() { recvmsg(0, &msg, 0); }; expectRealtimeDeath(Func, "recvmsg"); expectNonrealtimeSurvival(Func); } diff --git a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h index 61d55ac5c9658..068f8805d5b85 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h +++ b/compiler-rt/lib/radsan/tests/radsan_test_utilities.h @@ -29,7 +29,7 @@ void expectRealtimeDeath(Function &&Func, using namespace testing; - auto ExpectedErrorSubstring = [&]() -> std::string { + auto GetExpectedErrorSubstring = [&]() -> std::string { return intercepted_method_name != nullptr ? "Real-time violation: intercepted call to real-time unsafe " "function `" + @@ -38,7 +38,7 @@ void expectRealtimeDeath(Function &&Func, }; EXPECT_EXIT(RealtimeInvoke(std::forward(Func)), - ExitedWithCode(EXIT_FAILURE), ExpectedErrorSubstring()); + ExitedWithCode(EXIT_FAILURE), GetExpectedErrorSubstring()); } template void expectNonrealtimeSurvival(Function &&Func) { From 18da2b4f8884551b450b5dcb6bcd6e6ee86f14db Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Mon, 20 May 2024 09:08:50 -0700 Subject: [PATCH 23/47] PR: Fix style nit --- clang/lib/Driver/ToolChains/CommonArgs.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index ecac13e821cec..da8361bc1939e 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1464,9 +1464,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, StaticRuntimes.push_back("asan_cxx"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsRadsanRt()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsRadsanRt()) StaticRuntimes.push_back("radsan"); - } if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt()) { StaticRuntimes.push_back("memprof"); From d7c33375ca019d14a602ae66fb923c692f8fc005 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Mon, 20 May 2024 09:10:17 -0700 Subject: [PATCH 24/47] PR: Fix small style fallout --- clang/lib/Driver/ToolChains/CommonArgs.cpp | 2 +- compiler-rt/lib/radsan/radsan_interceptors.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index da8361bc1939e..b407eb79db866 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1464,7 +1464,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, StaticRuntimes.push_back("asan_cxx"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsRadsanRt()) + if (!SanArgs.needsSharedRt() && SanArgs.needsRadsanRt()) StaticRuntimes.push_back("radsan"); if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt()) { diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp index 0816da4a113c1..d46994b2ef887 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.cpp +++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp @@ -140,7 +140,7 @@ INTERCEPTOR(int, puts, const char *s) { return REAL(puts)(s); } - // Concurrency +// Concurrency #if SANITIZER_APPLE #pragma clang diagnostic push // OSSpinLockLock is deprecated, but still in use in libc++ From 7cddba827e38ed50695313b4e79be209651b1bab Mon Sep 17 00:00:00 2001 From: David Trevelyan Date: Tue, 21 May 2024 09:22:04 +0100 Subject: [PATCH 25/47] Update comment and TU-local function style --- compiler-rt/lib/radsan/radsan.h | 36 ++++++++------------- compiler-rt/lib/radsan/radsan_context.cpp | 39 +++++++++-------------- compiler-rt/lib/radsan/radsan_stack.cpp | 5 +-- 3 files changed, 29 insertions(+), 51 deletions(-) diff --git a/compiler-rt/lib/radsan/radsan.h b/compiler-rt/lib/radsan/radsan.h index d8bfc13c22c25..50e4630b00d73 100644 --- a/compiler-rt/lib/radsan/radsan.h +++ b/compiler-rt/lib/radsan/radsan.h @@ -12,37 +12,27 @@ extern "C" { -/** Initialise radsan interceptors. - - A call to this method is added to the preinit array on Linux systems. -*/ +// Initialise radsan interceptors. +// A call to this method is added to the preinit array on Linux systems. SANITIZER_INTERFACE_ATTRIBUTE void __radsan_init(); -/** Enter real-time context. - - When in a real-time context, RADSan interceptors will error if realtime - violations are detected. Calls to this method are injected at the code - generation stage when RADSan is enabled. -*/ +// Enter real-time context. +// When in a real-time context, RADSan interceptors will error if realtime +// violations are detected. Calls to this method are injected at the code +// generation stage when RADSan is enabled. SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_enter(); -/** Exit the real-time context. - - When not in a real-time context, RADSan interceptors will simply forward - intercepted method calls to the real methods. -*/ +// Exit the real-time context. +// When not in a real-time context, RADSan interceptors will simply forward +// intercepted method calls to the real methods. SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_exit(); -/** Disable all RADSan error reporting. - - Injected into the code if "nosanitize(realtime)" is on a function. -*/ +// Disable all RADSan error reporting. +// Injected into the code if "nosanitize(realtime)" is on a function. SANITIZER_INTERFACE_ATTRIBUTE void __radsan_off(); -/** Re-enable all RADSan error reporting. - - The counterpart to `__radsan_off`. -*/ +// Re-enable all RADSan error reporting. +// The counterpart to `__radsan_off`. SANITIZER_INTERFACE_ATTRIBUTE void __radsan_on(); } // extern "C" diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/radsan/radsan_context.cpp index bc1ab4d0369cc..cb7a2e75c632d 100644 --- a/compiler-rt/lib/radsan/radsan_context.cpp +++ b/compiler-rt/lib/radsan/radsan_context.cpp @@ -18,29 +18,24 @@ #include #include -using namespace __sanitizer; - -namespace detail { - -static pthread_key_t key; +static pthread_key_t context_key; static pthread_once_t key_once = PTHREAD_ONCE_INIT; -void internalFree(void *ptr) { __sanitizer::InternalFree(ptr); } -using __radsan::Context; +static void internalFree(void *ptr) { __sanitizer::InternalFree(ptr); } -Context &GetContextForThisThreadImpl() { - auto make_tls_key = []() { - CHECK_EQ(pthread_key_create(&detail::key, detail::internalFree), 0); +static __radsan::Context &GetContextForThisThreadImpl() { + auto make_thread_local_context_key = []() { + CHECK_EQ(pthread_key_create(&context_key, internalFree), 0); }; - pthread_once(&detail::key_once, make_tls_key); - Context *current_thread_context = - static_cast(pthread_getspecific(detail::key)); + pthread_once(&key_once, make_thread_local_context_key); + __radsan::Context *current_thread_context = + static_cast<__radsan::Context *>(pthread_getspecific(context_key)); if (current_thread_context == nullptr) { - current_thread_context = - static_cast(InternalAlloc(sizeof(Context))); - new (current_thread_context) Context(); - pthread_setspecific(detail::key, current_thread_context); + current_thread_context = static_cast<__radsan::Context *>( + __sanitizer::InternalAlloc(sizeof(__radsan::Context))); + new (current_thread_context) __radsan::Context(); + pthread_setspecific(context_key, current_thread_context); } return *current_thread_context; @@ -60,9 +55,7 @@ Context &GetContextForThisThreadImpl() { Until then, and to keep the first PRs small, only the exit mode is available. */ -void InvokeViolationDetectedAction() { exit(EXIT_FAILURE); } - -} // namespace detail +static void InvokeViolationDetectedAction() { exit(EXIT_FAILURE); } namespace __radsan { @@ -80,7 +73,7 @@ void Context::ExpectNotRealtime(const char *intercepted_function_name) { if (InRealtimeContext() && !IsBypassed()) { BypassPush(); PrintDiagnostics(intercepted_function_name); - detail::InvokeViolationDetectedAction(); + InvokeViolationDetectedAction(); BypassPop(); } } @@ -97,8 +90,6 @@ void Context::PrintDiagnostics(const char *intercepted_function_name) { __radsan::PrintStackTrace(); } -Context &GetContextForThisThread() { - return detail::GetContextForThisThreadImpl(); -} +Context &GetContextForThisThread() { return GetContextForThisThreadImpl(); } } // namespace __radsan diff --git a/compiler-rt/lib/radsan/radsan_stack.cpp b/compiler-rt/lib/radsan/radsan_stack.cpp index eb941869397e6..debd9777f5dbc 100644 --- a/compiler-rt/lib/radsan/radsan_stack.cpp +++ b/compiler-rt/lib/radsan/radsan_stack.cpp @@ -15,7 +15,6 @@ using namespace __sanitizer; // We must define our own implementation of this method for our runtime. // This one is just copied from UBSan. - namespace __sanitizer { void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { @@ -27,8 +26,7 @@ void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context, } } // namespace __sanitizer -namespace __radsan { -void SetGlobalStackTraceFormat() { +static void SetGlobalStackTraceFormat() { SetCommonFlagsDefaults(); CommonFlags cf; cf.CopyFrom(*common_flags()); @@ -36,7 +34,6 @@ void SetGlobalStackTraceFormat() { cf.external_symbolizer_path = GetEnv("RADSAN_SYMBOLIZER_PATH"); OverrideCommonFlags(cf); } -} // namespace __radsan using namespace __radsan; void __radsan::PrintStackTrace() { From 9be12a9b3aeb2669c6088a0bffdeee33a14d540d Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Tue, 21 May 2024 13:46:02 -0700 Subject: [PATCH 26/47] PR: Remove too early inclusion of sanitizer common lit tests --- compiler-rt/test/sanitizer_common/CMakeLists.txt | 2 +- compiler-rt/test/sanitizer_common/lit.common.cfg.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/compiler-rt/test/sanitizer_common/CMakeLists.txt b/compiler-rt/test/sanitizer_common/CMakeLists.txt index 1c37cf2a0c721..edecc04d48c75 100644 --- a/compiler-rt/test/sanitizer_common/CMakeLists.txt +++ b/compiler-rt/test/sanitizer_common/CMakeLists.txt @@ -7,7 +7,7 @@ set(SANITIZER_COMMON_TESTSUITES) # FIXME(dliew): We should switch to COMPILER_RT_SANITIZERS_TO_BUILD instead of # the hard coded `SUPPORTED_TOOLS_INIT` list once we know that the other # sanitizers work. -set(SUPPORTED_TOOLS_INIT asan lsan hwasan msan radsan tsan ubsan) +set(SUPPORTED_TOOLS_INIT asan lsan hwasan msan tsan ubsan) set(SUPPORTED_TOOLS) foreach(SANITIZER_TOOL ${SUPPORTED_TOOLS_INIT}) string(TOUPPER ${SANITIZER_TOOL} SANITIZER_TOOL_UPPER) diff --git a/compiler-rt/test/sanitizer_common/lit.common.cfg.py b/compiler-rt/test/sanitizer_common/lit.common.cfg.py index 80c7372372f44..04af4816eb6e7 100644 --- a/compiler-rt/test/sanitizer_common/lit.common.cfg.py +++ b/compiler-rt/test/sanitizer_common/lit.common.cfg.py @@ -18,9 +18,6 @@ tool_options = "HWASAN_OPTIONS" if not config.has_lld: config.unsupported = True -elif config.tool_name == "radsan": - tool_cflags = ["-fsanitize=realtime"] - tool_options = "RADSAN_OPTIONS" elif config.tool_name == "tsan": tool_cflags = ["-fsanitize=thread"] tool_options = "TSAN_OPTIONS" From c9accb3c1a9845790bbbdedadd404289baa17b61 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Thu, 30 May 2024 09:46:19 -0700 Subject: [PATCH 27/47] Test failure: fix initialization of pthread_cond_t --- compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp index 353643559b82e..ff19aa84e46e8 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp @@ -372,12 +372,16 @@ TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) { } TEST(TestRadsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) { + pthread_cond_t cond; + pthread_cond_init(&cond, NULL); auto Func = []() { pthread_cond_t cond; pthread_cond_broadcast(&cond); }; expectRealtimeDeath(Func, "pthread_cond_broadcast"); expectNonrealtimeSurvival(Func); + + pthread_cond_destroy(&cond); } TEST(TestRadsanInterceptors, PthreadCondWaitDiesWhenRealtime) { From 0934d3443d5f210c63ecc1a4a3358ccd158efced Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Thu, 30 May 2024 12:01:58 -0700 Subject: [PATCH 28/47] Test failure: Try again with initialization of pthread_cond_t --- compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp index ff19aa84e46e8..2093b3a85b87a 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp @@ -372,10 +372,9 @@ TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) { } TEST(TestRadsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) { - pthread_cond_t cond; + pthread_cond_t cond{}; pthread_cond_init(&cond, NULL); - auto Func = []() { - pthread_cond_t cond; + auto Func = [&cond]() { pthread_cond_broadcast(&cond); }; expectRealtimeDeath(Func, "pthread_cond_broadcast"); From b1fb26878550edcc14ca1231410e74d15ce0a80d Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Thu, 30 May 2024 15:26:16 -0700 Subject: [PATCH 29/47] Fix code formatting on unit test --- compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp index 2093b3a85b87a..c24c8afdfbf87 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp @@ -374,9 +374,7 @@ TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) { TEST(TestRadsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) { pthread_cond_t cond{}; pthread_cond_init(&cond, NULL); - auto Func = [&cond]() { - pthread_cond_broadcast(&cond); - }; + auto Func = [&cond]() { pthread_cond_broadcast(&cond); }; expectRealtimeDeath(Func, "pthread_cond_broadcast"); expectNonrealtimeSurvival(Func); From 69d81c64fcbb9351831b9e34d86bf780e51adc5f Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Thu, 30 May 2024 16:36:50 -0700 Subject: [PATCH 30/47] Ensure all pthread_cond_t are initialized in unit tests --- .../lib/radsan/tests/radsan_test_interceptors.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp index c24c8afdfbf87..9d9c30784640d 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp @@ -363,17 +363,20 @@ TEST(TestRadsanInterceptors, SpinLockLockDiesWhenRealtime) { #endif TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) { - auto Func = []() { - pthread_cond_t cond{}; - pthread_cond_signal(&cond); - }; + pthread_cond_t cond{}; + pthread_cond_init(&cond, NULL); + + auto Func = [&cond]() { pthread_cond_signal(&cond); }; expectRealtimeDeath(Func, "pthread_cond_signal"); expectNonrealtimeSurvival(Func); + + pthread_cond_destroy(&cond); } TEST(TestRadsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) { pthread_cond_t cond{}; pthread_cond_init(&cond, NULL); + auto Func = [&cond]() { pthread_cond_broadcast(&cond); }; expectRealtimeDeath(Func, "pthread_cond_broadcast"); expectNonrealtimeSurvival(Func); @@ -386,11 +389,15 @@ TEST(TestRadsanInterceptors, PthreadCondWaitDiesWhenRealtime) { pthread_mutex_t mutex; ASSERT_EQ(0, pthread_cond_init(&cond, nullptr)); ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr)); + auto Func = [&]() { pthread_cond_wait(&cond, &mutex); }; expectRealtimeDeath(Func, "pthread_cond_wait"); // It's very difficult to test the success case here without doing some // sleeping, which is at the mercy of the scheduler. What's really important // here is the interception - so we're only testing that for now. + + pthread_cond_destroy(&cond); + pthread_mutex_destroy(&mutex); } TEST(TestRadsanInterceptors, PthreadRwlockRdlockDiesWhenRealtime) { From d30cc80769ce517538a63ae05f3102898af62052 Mon Sep 17 00:00:00 2001 From: Chris Apple Date: Fri, 31 May 2024 06:34:56 -0700 Subject: [PATCH 31/47] Fix issue where CREAT flag was not properly passing mode (#23) * Pass on CREAT mode propertly in open interceptors * Add unit tests * Remove two unneccessary bits * Fix fcntl --- .../lib/radsan/radsan_interceptors.cpp | 17 +++------ .../radsan/tests/radsan_test_interceptors.cpp | 38 +++++++++++++++++++ 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp index d46994b2ef887..793bdbc6f868c 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.cpp +++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp @@ -52,6 +52,7 @@ INTERCEPTOR(int, open, const char *path, int oflag, ...) { // TODO Establish whether we should intercept here if the flag contains // O_NONBLOCK __radsan::ExpectNotRealtime("open"); + va_list args; va_start(args, oflag); const mode_t mode = va_arg(args, int); @@ -65,6 +66,7 @@ INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) { // TODO Establish whether we should intercept here if the flag contains // O_NONBLOCK __radsan::ExpectNotRealtime("openat"); + va_list args; va_start(args, oflag); mode_t mode = va_arg(args, int); @@ -84,22 +86,13 @@ INTERCEPTOR(int, creat, const char *path, mode_t mode) { INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) { __radsan::ExpectNotRealtime("fcntl"); + va_list args; va_start(args, cmd); - - // Following precedent here. The linux source (fcntl.c, do_fcntl) accepts the - // final argument in a variable that will hold the largest of the possible - // argument types (pointers and ints are typical in fcntl) It is then assumed - // that the implementation of fcntl will cast it properly depending on cmd. - // - // This is also similar to what is done in - // sanitizer_common/sanitizer_common_syscalls.inc - const unsigned long arg = va_arg(args, unsigned long); - int result = REAL(fcntl)(filedes, cmd, arg); - + void *arg = va_arg(args, void *); va_end(args); - return result; + return fcntl(filedes, cmd, arg); } INTERCEPTOR(int, close, int filedes) { diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp index 9d9c30784640d..67b6cc210d29e 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp @@ -204,6 +204,22 @@ TEST(TestRadsanInterceptors, OpenatDiesWhenRealtime) { std::remove(TemporaryFilePath()); } +TEST(TestRadsanInterceptors, openCreatesFileWithProperMode) { + const int mode = S_IRGRP | S_IROTH | S_IRUSR | S_IWUSR; + + const int fd = open(TemporaryFilePath(), O_CREAT | O_WRONLY, mode); + ASSERT_THAT(fd, Ne(-1)); + close(fd); + + struct stat st; + ASSERT_THAT(stat(TemporaryFilePath(), &st), Eq(0)); + + // Mask st_mode to get permission bits only + ASSERT_THAT(st.st_mode & 0777, Eq(mode)); + + std::remove(TemporaryFilePath()); +} + TEST(TestRadsanInterceptors, CreatDiesWhenRealtime) { auto Func = []() { creat(TemporaryFilePath(), S_IWOTH | S_IROTH); }; ExpectRealtimeDeath(Func, "creat"); @@ -217,6 +233,28 @@ TEST(TestRadsanInterceptors, FcntlDiesWhenRealtime) { ExpectNonRealtimeSurvival(Func); } +TEST(TestRadsanInterceptors, FcntlFlockDiesWhenRealtime) { + int fd = creat(TemporaryFilePath(), S_IRUSR | S_IWUSR); + ASSERT_THAT(fd, Ne(-1)); + + auto func = [fd]() { + struct flock lock {}; + lock.l_type = F_RDLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + lock.l_pid = ::getpid(); + + ASSERT_THAT(fcntl(fd, F_GETLK, &lock), Eq(0)); + ASSERT_THAT(lock.l_type, F_UNLCK); + }; + ExpectRealtimeDeath(func, "fcntl"); + ExpectNonRealtimeSurvival(func); + + close(fd); + std::remove(TemporaryFilePath()); +} + TEST(TestRadsanInterceptors, CloseDiesWhenRealtime) { auto Func = []() { close(0); }; expectRealtimeDeath(Func, "close"); From 2f84934b0ce4939e8b89547419ad8f9863ba9e4b Mon Sep 17 00:00:00 2001 From: Chris Apple Date: Fri, 31 May 2024 14:15:51 -0700 Subject: [PATCH 32/47] Fix issue where fcntl was not using last arg correctly (#24) * Fix issue where fcntl was not using last arg correctly * Comment update --- .../lib/radsan/radsan_interceptors.cpp | 14 ++++++++++-- .../radsan/tests/radsan_test_interceptors.cpp | 22 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/radsan/radsan_interceptors.cpp index 793bdbc6f868c..0a4b7d3a349b0 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.cpp +++ b/compiler-rt/lib/radsan/radsan_interceptors.cpp @@ -89,10 +89,20 @@ INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) { va_list args; va_start(args, cmd); - void *arg = va_arg(args, void *); + + // Following precedent here. The linux source (fcntl.c, do_fcntl) accepts the + // final argument in a variable that will hold the largest of the possible + // argument types (pointers and ints are typical in fcntl) It is then assumed + // that the implementation of fcntl will cast it properly depending on cmd. + // + // This is also similar to what is done in + // sanitizer_common/sanitizer_common_syscalls.inc + const unsigned long arg = va_arg(args, unsigned long); + int result = REAL(fcntl)(filedes, cmd, arg); + va_end(args); - return fcntl(filedes, cmd, arg); + return result; } INTERCEPTOR(int, close, int filedes) { diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp index 67b6cc210d29e..9ab96b163393f 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp @@ -261,6 +261,28 @@ TEST(TestRadsanInterceptors, CloseDiesWhenRealtime) { expectNonrealtimeSurvival(Func); } +TEST(TestRadsanInterceptors, fcntlSetFdDiesWhenRealtime) { + int fd = creat(TemporaryFilePath(), S_IRUSR | S_IWUSR); + ASSERT_THAT(fd, Ne(-1)); + + auto func = [fd]() { + int old_flags = fcntl(fd, F_GETFD); + ASSERT_THAT(fcntl(fd, F_SETFD, FD_CLOEXEC), Eq(0)); + + int flags = fcntl(fd, F_GETFD); + ASSERT_THAT(flags, Ne(-1)); + ASSERT_THAT(flags & FD_CLOEXEC, Eq(FD_CLOEXEC)); + + ASSERT_THAT(fcntl(fd, F_SETFD, old_flags), Eq(0)); + ASSERT_THAT(fcntl(fd, F_GETFD), Eq(old_flags)); + }; + + ExpectRealtimeDeath(func, "fcntl"); + ExpectNonRealtimeSurvival(func); + + close(fd); +} + TEST(TestRadsanInterceptors, FopenDiesWhenRealtime) { auto Func = []() { FILE *fd = fopen(TemporaryFilePath(), "w"); From 4197052f4598b639166fb16e956c2b9fa1606e82 Mon Sep 17 00:00:00 2001 From: Chris Apple Date: Sat, 1 Jun 2024 08:55:50 -0700 Subject: [PATCH 33/47] Introduce test fixture for temporary files (#25) * Introduce test fixture for temporary files * Style fixup for method name --- .../radsan/tests/radsan_test_interceptors.cpp | 159 +++++++++--------- 1 file changed, 75 insertions(+), 84 deletions(-) diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp index 9ab96b163393f..942d1b33b9078 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp +++ b/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp @@ -39,24 +39,26 @@ using namespace testing; using namespace radsan_testing; using namespace std::chrono_literals; -namespace { void *FakeThreadEntryPoint(void *) { return nullptr; } -/* - The creat function doesn't seem to work on an ubuntu Docker image when the - path is in a shared volume of the host. For now, to keep testing convenient - with a local Docker container, we just put it somewhere that's not in the - shared volume (/tmp). This is volatile and will be cleaned up as soon as the - container is stopped. -*/ -constexpr const char *TemporaryFilePath() { -#if SANITIZER_LINUX - return "/tmp/radsan_temporary_test_file.txt"; -#elif SANITIZER_APPLE - return "./radsan_temporary_test_file.txt"; -#endif -} -} // namespace +class RadsanFileTest : public ::testing::Test { +protected: + void SetUp() override { + const ::testing::TestInfo *const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + file_path = std::string("/tmp/radsan_temporary_test_file_") + + test_info->name() + ".txt"; + } + + // Gets a file path with the test's name in in + // This file will be removed if it exists at the end of the test + const char *GetTemporaryFilePath() const { return file_path.c_str(); } + + void TearDown() override { std::remove(GetTemporaryFilePath()); } + +private: + std::string file_path; +}; class RadsanFileTest : public ::testing::Test { protected: @@ -190,51 +192,46 @@ TEST(TestRadsanInterceptors, NanosleepDiesWhenRealtime) { Filesystem */ -TEST(TestRadsanInterceptors, OpenDiesWhenRealtime) { - auto Func = []() { open(TemporaryFilePath(), O_RDONLY); }; - ExpectRealtimeDeath(Func, "open"); - ExpectNonRealtimeSurvival(Func); - std::remove(TemporaryFilePath()); +TEST_F(RadsanFileTest, OpenDiesWhenRealtime) { + auto func = [this]() { open(GetTemporaryFilePath(), O_RDONLY); }; + ExpectRealtimeDeath(func, "open"); + ExpectNonRealtimeSurvival(func); } -TEST(TestRadsanInterceptors, OpenatDiesWhenRealtime) { - auto Func = []() { openat(0, TemporaryFilePath(), O_RDONLY); }; - ExpectRealtimeDeath(Func, "openat"); - ExpectNonRealtimeSurvival(Func); - std::remove(TemporaryFilePath()); +TEST_F(RadsanFileTest, OpenatDiesWhenRealtime) { + auto func = [this]() { openat(0, GetTemporaryFilePath(), O_RDONLY); }; + ExpectRealtimeDeath(func, "openat"); + ExpectNonRealtimeSurvival(func); } -TEST(TestRadsanInterceptors, openCreatesFileWithProperMode) { +TEST_F(RadsanFileTest, OpenCreatesFileWithProperMode) { const int mode = S_IRGRP | S_IROTH | S_IRUSR | S_IWUSR; - const int fd = open(TemporaryFilePath(), O_CREAT | O_WRONLY, mode); + const int fd = open(GetTemporaryFilePath(), O_CREAT | O_WRONLY, mode); ASSERT_THAT(fd, Ne(-1)); close(fd); struct stat st; - ASSERT_THAT(stat(TemporaryFilePath(), &st), Eq(0)); + ASSERT_THAT(stat(GetTemporaryFilePath(), &st), Eq(0)); // Mask st_mode to get permission bits only ASSERT_THAT(st.st_mode & 0777, Eq(mode)); - - std::remove(TemporaryFilePath()); } -TEST(TestRadsanInterceptors, CreatDiesWhenRealtime) { - auto Func = []() { creat(TemporaryFilePath(), S_IWOTH | S_IROTH); }; - ExpectRealtimeDeath(Func, "creat"); - ExpectNonRealtimeSurvival(Func); - std::remove(TemporaryFilePath()); +TEST_F(RadsanFileTest, CreatDiesWhenRealtime) { + auto func = [this]() { creat(GetTemporaryFilePath(), S_IWOTH | S_IROTH); }; + ExpectRealtimeDeath(func, "creat"); + ExpectNonRealtimeSurvival(func); } TEST(TestRadsanInterceptors, FcntlDiesWhenRealtime) { - auto Func = []() { fcntl(0, F_GETFL); }; - ExpectRealtimeDeath(Func, "fcntl"); - ExpectNonRealtimeSurvival(Func); + auto func = []() { fcntl(0, F_GETFL); }; + ExpectRealtimeDeath(func, "fcntl"); + ExpectNonRealtimeSurvival(func); } -TEST(TestRadsanInterceptors, FcntlFlockDiesWhenRealtime) { - int fd = creat(TemporaryFilePath(), S_IRUSR | S_IWUSR); +TEST_F(RadsanFileTest, FcntlFlockDiesWhenRealtime) { + int fd = creat(GetTemporaryFilePath(), S_IRUSR | S_IWUSR); ASSERT_THAT(fd, Ne(-1)); auto func = [fd]() { @@ -252,17 +249,10 @@ TEST(TestRadsanInterceptors, FcntlFlockDiesWhenRealtime) { ExpectNonRealtimeSurvival(func); close(fd); - std::remove(TemporaryFilePath()); -} - -TEST(TestRadsanInterceptors, CloseDiesWhenRealtime) { - auto Func = []() { close(0); }; - expectRealtimeDeath(Func, "close"); - expectNonrealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, fcntlSetFdDiesWhenRealtime) { - int fd = creat(TemporaryFilePath(), S_IRUSR | S_IWUSR); +TEST_F(RadsanFileTest, FcntlSetFdDiesWhenRealtime) { + int fd = creat(GetTemporaryFilePath(), S_IRUSR | S_IWUSR); ASSERT_THAT(fd, Ne(-1)); auto func = [fd]() { @@ -283,63 +273,64 @@ TEST(TestRadsanInterceptors, fcntlSetFdDiesWhenRealtime) { close(fd); } -TEST(TestRadsanInterceptors, FopenDiesWhenRealtime) { - auto Func = []() { - FILE *fd = fopen(TemporaryFilePath(), "w"); +TEST(TestRadsanInterceptors, CloseDiesWhenRealtime) { + auto func = []() { close(0); }; + ExpectRealtimeDeath(func, "close"); + ExpectNonRealtimeSurvival(func); +} + +TEST_F(RadsanFileTest, FopenDiesWhenRealtime) { + auto func = [this]() { + auto fd = fopen(GetTemporaryFilePath(), "w"); EXPECT_THAT(fd, Ne(nullptr)); }; - ExpectRealtimeDeath(Func, "fopen"); - ExpectNonRealtimeSurvival(Func); - std::remove(TemporaryFilePath()); + ExpectRealtimeDeath(func, "fopen"); + ExpectNonRealtimeSurvival(func); } -TEST(TestRadsanInterceptors, FreadDiesWhenRealtime) { - FILE *fd = fopen(TemporaryFilePath(), "w"); - auto Func = [fd]() { +TEST_F(RadsanFileTest, FreadDiesWhenRealtime) { + auto fd = fopen(GetTemporaryFilePath(), "w"); + auto func = [fd]() { char c{}; fread(&c, 1, 1, fd); }; - ExpectRealtimeDeath(Func, "fread"); - ExpectNonRealtimeSurvival(Func); + ExpectRealtimeDeath(func, "fread"); + ExpectNonRealtimeSurvival(func); if (fd != nullptr) fclose(fd); - std::remove(TemporaryFilePath()); } -TEST(TestRadsanInterceptors, FwriteDiesWhenRealtime) { - FILE *fd = fopen(TemporaryFilePath(), "w"); +TEST_F(RadsanFileTest, FwriteDiesWhenRealtime) { + auto fd = fopen(GetTemporaryFilePath(), "w"); ASSERT_NE(nullptr, fd); - const char *message = "Hello, world!"; - auto Func = [&]() { fwrite(&message, 1, 4, fd); }; - ExpectRealtimeDeath(Func, "fwrite"); - ExpectNonRealtimeSurvival(Func); - std::remove(TemporaryFilePath()); + auto message = "Hello, world!"; + auto func = [&]() { fwrite(&message, 1, 4, fd); }; + ExpectRealtimeDeath(func, "fwrite"); + ExpectNonRealtimeSurvival(func); } -TEST(TestRadsanInterceptors, FcloseDiesWhenRealtime) { - FILE *fd = fopen(TemporaryFilePath(), "w"); +TEST_F(RadsanFileTest, FcloseDiesWhenRealtime) { + auto fd = fopen(GetTemporaryFilePath(), "w"); EXPECT_THAT(fd, Ne(nullptr)); - auto Func = [fd]() { fclose(fd); }; - ExpectRealtimeDeath(Func, "fclose"); - ExpectNonRealtimeSurvival(Func); - std::remove(TemporaryFilePath()); + auto func = [fd]() { fclose(fd); }; + ExpectRealtimeDeath(func, "fclose"); + ExpectNonRealtimeSurvival(func); } TEST(TestRadsanInterceptors, PutsDiesWhenRealtime) { - auto Func = []() { puts("Hello, world!\n"); }; - expectRealtimeDeath(Func); - expectNonrealtimeSurvival(Func); + auto func = []() { puts("Hello, world!\n"); }; + expectRealtimeDeath(func); + expectNonrealtimeSurvival(func); } -TEST(TestRadsanInterceptors, FputsDiesWhenRealtime) { - FILE *fd = fopen(TemporaryFilePath(), "w"); +TEST_F(RadsanFileTest, FputsDiesWhenRealtime) { + auto fd = fopen(GetTemporaryFilePath(), "w"); ASSERT_THAT(fd, Ne(nullptr)) << errno; - auto Func = [fd]() { fputs("Hello, world!\n", fd); }; - ExpectRealtimeDeath(Func); - ExpectNonRealtimeSurvival(Func); + auto func = [fd]() { fputs("Hello, world!\n", fd); }; + ExpectRealtimeDeath(func); + ExpectNonRealtimeSurvival(func); if (fd != nullptr) fclose(fd); - std::remove(TemporaryFilePath()); } /* From 3a562d5eebde9fe48b6de16846c33363bcdc70e1 Mon Sep 17 00:00:00 2001 From: David Trevelyan Date: Mon, 3 Jun 2024 21:57:36 +0100 Subject: [PATCH 34/47] Rename RADSan to RTSan --- clang/include/clang/Driver/SanitizerArgs.h | 2 +- clang/lib/Driver/ToolChains/CommonArgs.cpp | 4 +- clang/lib/Driver/ToolChains/Darwin.cpp | 6 +- clang/runtime/CMakeLists.txt | 2 +- compiler-rt/CODE_OWNERS.TXT | 2 +- .../cmake/Modules/AllSupportedArchDefs.cmake | 2 +- compiler-rt/cmake/config-ix.cmake | 14 +- compiler-rt/lib/radsan/CMakeLists.txt | 92 ------ compiler-rt/lib/radsan/radsan.cpp | 35 --- compiler-rt/lib/radsan/radsan.h | 38 --- compiler-rt/lib/radsan/radsan_context.h | 36 --- compiler-rt/lib/radsan/radsan_preinit.cpp | 21 -- compiler-rt/lib/radsan/radsan_stack.h | 13 - compiler-rt/lib/radsan/tests/CMakeLists.txt | 103 ------- .../lib/radsan/tests/radsan_test_main.cpp | 15 - compiler-rt/lib/rtsan/CMakeLists.txt | 92 ++++++ compiler-rt/lib/rtsan/rtsan.cpp | 37 +++ compiler-rt/lib/rtsan/rtsan.h | 40 +++ .../rtsan_context.cpp} | 44 +-- compiler-rt/lib/rtsan/rtsan_context.h | 38 +++ .../rtsan_interceptors.cpp} | 117 ++++---- .../rtsan_interceptors.h} | 7 +- compiler-rt/lib/rtsan/rtsan_preinit.cpp | 23 ++ .../rtsan_stack.cpp} | 26 +- compiler-rt/lib/rtsan/rtsan_stack.h | 15 + compiler-rt/lib/rtsan/tests/CMakeLists.txt | 103 +++++++ .../tests/rtsan_test_context.cpp} | 33 ++- .../tests/rtsan_test_functional.cpp} | 114 ++++---- .../tests/rtsan_test_interceptors.cpp} | 262 ++++++++---------- .../lib/rtsan/tests/rtsan_test_main.cpp | 17 ++ .../tests/rtsan_test_utilities.h} | 13 +- compiler-rt/test/radsan/CMakeLists.txt | 58 ---- compiler-rt/test/rtsan/CMakeLists.txt | 58 ++++ .../{radsan => rtsan}/Unit/lit.site.cfg.py.in | 12 +- compiler-rt/test/{radsan => rtsan}/lit.cfg.py | 26 +- .../test/{radsan => rtsan}/lit.site.cfg.py.in | 8 +- 36 files changed, 760 insertions(+), 768 deletions(-) delete mode 100644 compiler-rt/lib/radsan/CMakeLists.txt delete mode 100644 compiler-rt/lib/radsan/radsan.cpp delete mode 100644 compiler-rt/lib/radsan/radsan.h delete mode 100644 compiler-rt/lib/radsan/radsan_context.h delete mode 100644 compiler-rt/lib/radsan/radsan_preinit.cpp delete mode 100644 compiler-rt/lib/radsan/radsan_stack.h delete mode 100644 compiler-rt/lib/radsan/tests/CMakeLists.txt delete mode 100644 compiler-rt/lib/radsan/tests/radsan_test_main.cpp create mode 100644 compiler-rt/lib/rtsan/CMakeLists.txt create mode 100644 compiler-rt/lib/rtsan/rtsan.cpp create mode 100644 compiler-rt/lib/rtsan/rtsan.h rename compiler-rt/lib/{radsan/radsan_context.cpp => rtsan/rtsan_context.cpp} (63%) create mode 100644 compiler-rt/lib/rtsan/rtsan_context.h rename compiler-rt/lib/{radsan/radsan_interceptors.cpp => rtsan/rtsan_interceptors.cpp} (78%) rename compiler-rt/lib/{radsan/radsan_interceptors.h => rtsan/rtsan_interceptors.h} (76%) create mode 100644 compiler-rt/lib/rtsan/rtsan_preinit.cpp rename compiler-rt/lib/{radsan/radsan_stack.cpp => rtsan/rtsan_stack.cpp} (62%) create mode 100644 compiler-rt/lib/rtsan/rtsan_stack.h create mode 100644 compiler-rt/lib/rtsan/tests/CMakeLists.txt rename compiler-rt/lib/{radsan/tests/radsan_test_context.cpp => rtsan/tests/rtsan_test_context.cpp} (64%) rename compiler-rt/lib/{radsan/tests/radsan_test_functional.cpp => rtsan/tests/rtsan_test_functional.cpp} (58%) rename compiler-rt/lib/{radsan/tests/radsan_test_interceptors.cpp => rtsan/tests/rtsan_test_interceptors.cpp} (57%) create mode 100644 compiler-rt/lib/rtsan/tests/rtsan_test_main.cpp rename compiler-rt/lib/{radsan/tests/radsan_test_utilities.h => rtsan/tests/rtsan_test_utilities.h} (85%) delete mode 100644 compiler-rt/test/radsan/CMakeLists.txt create mode 100644 compiler-rt/test/rtsan/CMakeLists.txt rename compiler-rt/test/{radsan => rtsan}/Unit/lit.site.cfg.py.in (65%) rename compiler-rt/test/{radsan => rtsan}/lit.cfg.py (64%) rename compiler-rt/test/{radsan => rtsan}/lit.site.cfg.py.in (69%) diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h index f059c8715e26d..6c0df926aec5b 100644 --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -79,7 +79,7 @@ class SanitizerArgs { bool needsStableAbi() const { return StableABI; } bool needsMemProfRt() const { return NeedsMemProfRt; } - bool needsRadsanRt() const { return Sanitizers.has(SanitizerKind::Realtime); } + bool needsRtsanRt() const { return Sanitizers.has(SanitizerKind::Realtime); } bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); } bool needsHwasanRt() const { return Sanitizers.has(SanitizerKind::HWAddress); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index b407eb79db866..c75e5a84b005d 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1464,8 +1464,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, StaticRuntimes.push_back("asan_cxx"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsRadsanRt()) - StaticRuntimes.push_back("radsan"); + if (!SanArgs.needsSharedRt() && SanArgs.needsRtsanRt()) + StaticRuntimes.push_back("rtsan"); if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt()) { StaticRuntimes.push_back("memprof"); diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index b3e9d14021cda..0c1c13edfdd45 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -1496,7 +1496,7 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, const char *sanitizer = nullptr; if (Sanitize.needsUbsanRt()) { sanitizer = "UndefinedBehaviorSanitizer"; - } else if (Sanitize.needsRadsanRt()) { + } else if (Sanitize.needsRtsanRt()) { sanitizer = "RealtimeSanitizer"; } else if (Sanitize.needsAsanRt()) { sanitizer = "AddressSanitizer"; @@ -1520,10 +1520,10 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, AddLinkSanitizerLibArgs(Args, CmdArgs, "asan"); } } - if (Sanitize.needsRadsanRt()) { + if (Sanitize.needsRtsanRt()) { assert(Sanitize.needsSharedRt() && "Static sanitizer runtimes not supported"); - AddLinkSanitizerLibArgs(Args, CmdArgs, "radsan"); + AddLinkSanitizerLibArgs(Args, CmdArgs, "rtsan"); } if (Sanitize.needsLsanRt()) AddLinkSanitizerLibArgs(Args, CmdArgs, "lsan"); diff --git a/clang/runtime/CMakeLists.txt b/clang/runtime/CMakeLists.txt index c56bff11d476b..109de3d737548 100644 --- a/clang/runtime/CMakeLists.txt +++ b/clang/runtime/CMakeLists.txt @@ -150,7 +150,7 @@ if(LLVM_BUILD_EXTERNAL_COMPILER_RT AND EXISTS ${COMPILER_RT_SRC_ROOT}/) check-lsan check-msan check-profile - check-radsan + check-rtsan check-safestack check-sanitizer check-tsan diff --git a/compiler-rt/CODE_OWNERS.TXT b/compiler-rt/CODE_OWNERS.TXT index 2db0357fc1a7f..570ab86508060 100644 --- a/compiler-rt/CODE_OWNERS.TXT +++ b/compiler-rt/CODE_OWNERS.TXT @@ -70,4 +70,4 @@ D: Profile runtime library N: Christopher Apple, David Trevelyan E: cja-private@pm.me, realtime.sanitizer@gmail.com -D: Realtime Sanitizer (RADSan) +D: Realtime Sanitizer (RTSan) diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake index 56a3a2590b999..bc152e304aaaf 100644 --- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake +++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake @@ -32,7 +32,7 @@ set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} ${LOONGARCH64}) set(ALL_ASAN_ABI_SUPPORTED_ARCH ${X86_64} ${ARM64} ${ARM64_32}) set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${LOONGARCH64}) -set(ALL_RADSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} +set(ALL_RTSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} ${LOONGARCH64}) diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index 6d75cd9cdf23a..3ee820f794717 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -597,8 +597,8 @@ if(APPLE) list_intersect(ASAN_SUPPORTED_ARCH ALL_ASAN_SUPPORTED_ARCH SANITIZER_COMMON_SUPPORTED_ARCH) - list_intersect(RADSAN_SUPPORTED_ARCH - ALL_RADSAN_SUPPORTED_ARCH + list_intersect(RTSAN_SUPPORTED_ARCH + ALL_RTSAN_SUPPORTED_ARCH SANITIZER_COMMON_SUPPORTED_ARCH) list_intersect(DFSAN_SUPPORTED_ARCH ALL_DFSAN_SUPPORTED_ARCH @@ -666,7 +666,7 @@ else() filter_available_targets(UBSAN_COMMON_SUPPORTED_ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH}) filter_available_targets(ASAN_SUPPORTED_ARCH ${ALL_ASAN_SUPPORTED_ARCH}) - filter_available_targets(RADSAN_SUPPORTED_ARCH ${ALL_RADSAN_SUPPORTED_ARCH}) + filter_available_targets(RTSAN_SUPPORTED_ARCH ${ALL_RTSAN_SUPPORTED_ARCH}) filter_available_targets(FUZZER_SUPPORTED_ARCH ${ALL_FUZZER_SUPPORTED_ARCH}) filter_available_targets(DFSAN_SUPPORTED_ARCH ${ALL_DFSAN_SUPPORTED_ARCH}) filter_available_targets(LSAN_SUPPORTED_ARCH ${ALL_LSAN_SUPPORTED_ARCH}) @@ -720,7 +720,7 @@ if(COMPILER_RT_SUPPORTED_ARCH) endif() message(STATUS "Compiler-RT supported architectures: ${COMPILER_RT_SUPPORTED_ARCH}") -set(ALL_SANITIZERS asan;radsan;dfsan;msan;hwasan;tsan;safestack;cfi;scudo_standalone;ubsan_minimal;gwp_asan;nsan;asan_abi) +set(ALL_SANITIZERS asan;rtsan;dfsan;msan;hwasan;tsan;safestack;cfi;scudo_standalone;ubsan_minimal;gwp_asan;nsan;asan_abi) set(COMPILER_RT_SANITIZERS_TO_BUILD all CACHE STRING "sanitizers to build if supported on the target (all;${ALL_SANITIZERS})") list_replace(COMPILER_RT_SANITIZERS_TO_BUILD all "${ALL_SANITIZERS}") @@ -751,10 +751,10 @@ else() set(COMPILER_RT_HAS_ASAN FALSE) endif() -if (COMPILER_RT_HAS_SANITIZER_COMMON AND RADSAN_SUPPORTED_ARCH) - set(COMPILER_RT_HAS_RADSAN TRUE) +if (COMPILER_RT_HAS_SANITIZER_COMMON AND RTSAN_SUPPORTED_ARCH) + set(COMPILER_RT_HAS_RTSAN TRUE) else() - set(COMPILER_RT_HAS_RADSAN FALSE) + set(COMPILER_RT_HAS_RTSAN FALSE) endif() if (OS_NAME MATCHES "Linux|FreeBSD|Windows|NetBSD|SunOS") diff --git a/compiler-rt/lib/radsan/CMakeLists.txt b/compiler-rt/lib/radsan/CMakeLists.txt deleted file mode 100644 index c7d1dacf3dbc7..0000000000000 --- a/compiler-rt/lib/radsan/CMakeLists.txt +++ /dev/null @@ -1,92 +0,0 @@ -include_directories(..) - -set(RADSAN_CXX_SOURCES - radsan.cpp - radsan_context.cpp - radsan_stack.cpp - radsan_interceptors.cpp) - -set(RADSAN_PREINIT_SOURCES - radsan_preinit.cpp) - -set(RADSAN_HEADERS - radsan.h - radsan_context.h - radsan_stack.h) - -set(RADSAN_DEPS) - -set(RADSAN_CFLAGS - ${COMPILER_RT_COMMON_CFLAGS} - ${COMPILER_RT_CXX_CFLAGS} - -DSANITIZER_COMMON_NO_REDEFINE_BUILTINS) -set(RADSAN_LINK_FLAGS ${COMPILER_RT_COMMON_LINK_FLAGS}) -set(RADSAN_LINK_LIBS - ${COMPILER_RT_UNWINDER_LINK_LIBS} - ${COMPILER_RT_CXX_LINK_LIBS}) - -if(APPLE) - add_compiler_rt_object_libraries(RTRadsan - OS ${SANITIZER_COMMON_SUPPORTED_OS} - ARCHS ${RADSAN_SUPPORTED_ARCH} - SOURCES ${RADSAN_CXX_SOURCES} - ADDITIONAL_HEADERS ${RADSAN_HEADERS} - CFLAGS ${RADSAN_CFLAGS} - DEPS ${RADSAN_DEPS}) -else() - add_compiler_rt_object_libraries(RTRadsan - ARCHS ${RADSAN_SUPPORTED_ARCH} - SOURCES ${RADSAN_CXX_SOURCES} - ADDITIONAL_HEADERS ${RADSAN_HEADERS} - CFLAGS ${RADSAN_CFLAGS} - DEPS ${RADSAN_DEPS}) - add_compiler_rt_object_libraries(RTRadsan_preinit - ARCHS ${RADSAN_SUPPORTED_ARCH} - SOURCES ${RADSAN_PREINIT_SOURCES} - ADDITIONAL_HEADERS ${RADSAN_HEADERS} - CFLAGS ${RADSAN_CFLAGS}) -endif() - -set(RADSAN_COMMON_RUNTIME_OBJECT_LIBS - RTInterception - RTSanitizerCommon - RTSanitizerCommonLibc - RTSanitizerCommonCoverage - RTSanitizerCommonSymbolizer) - -append_list_if(COMPILER_RT_HAS_LIBDL dl RADSAN_LINK_LIBS) -append_list_if(COMPILER_RT_HAS_LIBRT rt RADSAN_LINK_LIBS) -append_list_if(COMPILER_RT_HAS_LIBM m RADSAN_LINK_LIBS) -append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread RADSAN_LINK_LIBS) -append_list_if(COMPILER_RT_HAS_LIBLOG log RADSAN_LINK_LIBS) - -add_compiler_rt_component(radsan) - -if (APPLE) - add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS) - set(RADSAN_LINK_FLAGS ${RADSAN_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}) - - add_compiler_rt_runtime(clang_rt.radsan - SHARED - OS ${SANITIZER_COMMON_SUPPORTED_OS} - ARCHS ${RADSAN_SUPPORTED_ARCH} - OBJECT_LIBS RTRadsan - ${RADSAN_COMMON_RUNTIME_OBJECT_LIBS} - LINK_FLAGS ${RADSAN_LINK_FLAGS} - LINK_LIBS ${RADSAN_LINK_LIBS} - PARENT_TARGET radsan) -else() - add_compiler_rt_runtime(clang_rt.radsan - STATIC - ARCHS ${RADSAN_SUPPORTED_ARCH} - OBJECT_LIBS RTRadsan_preinit - RTRadsan - ${RADSAN_COMMON_RUNTIME_OBJECT_LIBS} - LINK_FLAGS ${RADSAN_LINK_FLAGS} - CFLAGS ${RADSAN_CFLAGS} - PARENT_TARGET radsan) -endif() - -if(COMPILER_RT_INCLUDE_TESTS) - add_subdirectory(tests) -endif() diff --git a/compiler-rt/lib/radsan/radsan.cpp b/compiler-rt/lib/radsan/radsan.cpp deleted file mode 100644 index 3cd8eb067f939..0000000000000 --- a/compiler-rt/lib/radsan/radsan.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/** - This file is part of the RealtimeSanitizer (RADSan) project. - https://github.com/realtime-sanitizer/radsan - - Copyright 2023 David Trevelyan & Alistair Barker - Subject to GNU General Public License (GPL) v3.0 -*/ - -#include -#include -#include - -extern "C" { - -SANITIZER_INTERFACE_ATTRIBUTE void __radsan_init() { - __radsan::InitializeInterceptors(); -} - -SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_enter() { - __radsan::GetContextForThisThread().RealtimePush(); -} - -SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_exit() { - __radsan::GetContextForThisThread().RealtimePop(); -} - -SANITIZER_INTERFACE_ATTRIBUTE void __radsan_off() { - __radsan::GetContextForThisThread().BypassPush(); -} - -SANITIZER_INTERFACE_ATTRIBUTE void __radsan_on() { - __radsan::GetContextForThisThread().BypassPop(); -} - -} // extern "C" diff --git a/compiler-rt/lib/radsan/radsan.h b/compiler-rt/lib/radsan/radsan.h deleted file mode 100644 index 50e4630b00d73..0000000000000 --- a/compiler-rt/lib/radsan/radsan.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - This file is part of the RealtimeSanitizer (RADSan) project. - https://github.com/realtime-sanitizer/radsan - - Copyright 2023 David Trevelyan & Alistair Barker - Subject to GNU General Public License (GPL) v3.0 -*/ - -#pragma once - -#include "sanitizer_common/sanitizer_internal_defs.h" - -extern "C" { - -// Initialise radsan interceptors. -// A call to this method is added to the preinit array on Linux systems. -SANITIZER_INTERFACE_ATTRIBUTE void __radsan_init(); - -// Enter real-time context. -// When in a real-time context, RADSan interceptors will error if realtime -// violations are detected. Calls to this method are injected at the code -// generation stage when RADSan is enabled. -SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_enter(); - -// Exit the real-time context. -// When not in a real-time context, RADSan interceptors will simply forward -// intercepted method calls to the real methods. -SANITIZER_INTERFACE_ATTRIBUTE void __radsan_realtime_exit(); - -// Disable all RADSan error reporting. -// Injected into the code if "nosanitize(realtime)" is on a function. -SANITIZER_INTERFACE_ATTRIBUTE void __radsan_off(); - -// Re-enable all RADSan error reporting. -// The counterpart to `__radsan_off`. -SANITIZER_INTERFACE_ATTRIBUTE void __radsan_on(); - -} // extern "C" diff --git a/compiler-rt/lib/radsan/radsan_context.h b/compiler-rt/lib/radsan/radsan_context.h deleted file mode 100644 index 1e4f9d314ca1a..0000000000000 --- a/compiler-rt/lib/radsan/radsan_context.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - This file is part of the RealtimeSanitizer (RADSan) project. - https://github.com/realtime-sanitizer/radsan - - Copyright 2023 David Trevelyan & Alistair Barker - Subject to GNU General Public License (GPL) v3.0 -*/ - -#pragma once - -namespace __radsan { - -class Context { -public: - Context(); - - void RealtimePush(); - void RealtimePop(); - - void BypassPush(); - void BypassPop(); - - void ExpectNotRealtime(const char *intercepted_function_name); - -private: - bool InRealtimeContext() const; - bool IsBypassed() const; - void PrintDiagnostics(const char *intercepted_function_name); - - int realtime_depth{0}; - int bypass_depth{0}; -}; - -Context &GetContextForThisThread(); - -} // namespace __radsan diff --git a/compiler-rt/lib/radsan/radsan_preinit.cpp b/compiler-rt/lib/radsan/radsan_preinit.cpp deleted file mode 100644 index 67be408156c03..0000000000000 --- a/compiler-rt/lib/radsan/radsan_preinit.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/** - This file is part of the RealtimeSanitizer (RADSan) project. - https://github.com/realtime-sanitizer/radsan - - Copyright 2023 David Trevelyan & Alistair Barker - Subject to GNU General Public License (GPL) v3.0 -*/ - -#include "sanitizer_common/sanitizer_internal_defs.h" -#include - -#if SANITIZER_CAN_USE_PREINIT_ARRAY - -// The symbol is called __local_radsan_preinit, because it's not intended to be -// exported. -// This code is linked into the main executable when -fsanitize=realtime is in -// the link flags. It can only use exported interface functions. -__attribute__((section(".preinit_array"), - used)) void (*__local_radsan_preinit)(void) = __radsan_init; - -#endif diff --git a/compiler-rt/lib/radsan/radsan_stack.h b/compiler-rt/lib/radsan/radsan_stack.h deleted file mode 100644 index f200de35e8585..0000000000000 --- a/compiler-rt/lib/radsan/radsan_stack.h +++ /dev/null @@ -1,13 +0,0 @@ -/** - This file is part of the RealtimeSanitizer (RADSan) project. - https://github.com/realtime-sanitizer/radsan - - Copyright 2023 David Trevelyan & Alistair Barker - Subject to GNU General Public License (GPL) v3.0 -*/ - -#pragma once - -namespace __radsan { -void PrintStackTrace(); -} // namespace __radsan diff --git a/compiler-rt/lib/radsan/tests/CMakeLists.txt b/compiler-rt/lib/radsan/tests/CMakeLists.txt deleted file mode 100644 index 79a3d2d3d6c23..0000000000000 --- a/compiler-rt/lib/radsan/tests/CMakeLists.txt +++ /dev/null @@ -1,103 +0,0 @@ -include(CompilerRTCompile) - -include_directories(..) - -set(RADSAN_UNITTEST_CFLAGS - ${COMPILER_RT_UNITTEST_CFLAGS} - ${COMPILER_RT_GTEST_CFLAGS} - ${COMPILER_RT_GMOCK_CFLAGS} - ${SANITIZER_TEST_CXX_CFLAGS} - -I${COMPILER_RT_SOURCE_DIR}/lib/ - -I${COMPILER_RT_SOURCE_DIR}/include/ - -I${COMPILER_RT_SOURCE_DIR}/lib/radsan - -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests - -DSANITIZER_COMMON_NO_REDEFINE_BUILTINS - -O2) - -set(RADSAN_INST_TEST_SOURCES - radsan_test_functional.cpp - radsan_test_interceptors.cpp - radsan_test_main.cpp) - -set(RADSAN_NOINST_TEST_SOURCES - ../radsan_preinit.cpp - radsan_test_context.cpp - radsan_test_main.cpp) - -set(RADSAN_UNITTEST_HEADERS - radsan_test_utilities.h) - -add_custom_target(RadsanUnitTests) -set_target_properties(RadsanUnitTests PROPERTIES FOLDER "Compiler-RT Tests") - -set(RADSAN_UNITTEST_LINK_FLAGS - ${COMPILER_RT_UNITTEST_LINK_FLAGS} - ${COMPILER_RT_UNWINDER_LINK_LIBS} - ${SANITIZER_TEST_CXX_LIBRARIES} - -no-pie) - -if (APPLE) - add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS) - list(APPEND RADSAN_UNITTEST_LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}) - list(APPEND RADSAN_UNITTEST_LINK_FLAGS ${DARWIN_osx_LINK_FLAGS}) - list(APPEND RADSAN_UNITTEST_CFLAGS ${DARWIN_osx_CFLAGS}) -else() - list(APPEND RADSAN_UNITTEST_LINK_FLAGS -latomic) -endif() - -set(COMPILER_RT_GOOGLETEST_SOURCES ${COMPILER_RT_GTEST_SOURCE} ${COMPILER_RT_GMOCK_SOURCE}) - -set(RADSAN_TEST_ARCH ${RADSAN_SUPPORTED_ARCH}) -if(APPLE) - darwin_filter_host_archs(RADSAN_SUPPORTED_ARCH RADSAN_TEST_ARCH) -endif() - -foreach(arch ${RADSAN_TEST_ARCH}) - set(RadsanTestObjects) - generate_compiler_rt_tests(RadsanTestObjects - RadsanUnitTests "Radsan-${arch}-Test" ${arch} - COMPILE_DEPS ${RADSAN_UNITTEST_HEADERS} - SOURCES ${RADSAN_INST_TEST_SOURCES} ${COMPILER_RT_GOOGLETEST_SOURCES} - DEPS llvm_gtest radsan - CFLAGS ${RADSAN_UNITTEST_CFLAGS} -fsanitize=realtime - LINK_FLAGS ${RADSAN_UNITTEST_LINK_FLAGS} -fsanitize=realtime) - set_target_properties(RadsanUnitTests PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - - set(RADSAN_TEST_RUNTIME RTRadsanTest.${arch}) - if(APPLE) - set(RADSAN_TEST_RUNTIME_OBJECTS - $ - $ - $ - $ - $ - $) - else() - set(RADSAN_TEST_RUNTIME_OBJECTS - $ - $ - $ - $ - $ - $ - $) - endif() - add_library(${RADSAN_TEST_RUNTIME} STATIC ${RADSAN_TEST_RUNTIME_OBJECTS}) - set_target_properties(${RADSAN_TEST_RUNTIME} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - FOLDER "Compiler-RT Runtime tests") - - set(RadsanNoInstTestObjects) - generate_compiler_rt_tests(RadsanNoInstTestObjects - RadsanUnitTests "Radsan-${arch}-NoInstTest" ${arch} - COMPILE_DEPS ${RADSAN_UNITTEST_HEADERS} - SOURCES ${RADSAN_NOINST_TEST_SOURCES} - ${COMPILER_RT_GOOGLETEST_SOURCES} - DEPS llvm_gtest - CFLAGS ${RADSAN_UNITTEST_CFLAGS} - LINK_FLAGS ${RADSAN_UNITTEST_LINK_FLAGS} - RUNTIME ${RADSAN_TEST_RUNTIME}) - set_target_properties(RadsanUnitTests PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) -endforeach() diff --git a/compiler-rt/lib/radsan/tests/radsan_test_main.cpp b/compiler-rt/lib/radsan/tests/radsan_test_main.cpp deleted file mode 100644 index f75dc2be2f0a1..0000000000000 --- a/compiler-rt/lib/radsan/tests/radsan_test_main.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/** - This file is part of the RealtimeSanitizer (RADSan) project. - https://github.com/realtime-sanitizer/radsan - - Copyright 2023 David Trevelyan & Alistair Barker - Subject to GNU General Public License (GPL) v3.0 -*/ - -#include "sanitizer_test_utils.h" - -int main(int argc, char **argv) { - testing::GTEST_FLAG(death_test_style) = "threadsafe"; - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/compiler-rt/lib/rtsan/CMakeLists.txt b/compiler-rt/lib/rtsan/CMakeLists.txt new file mode 100644 index 0000000000000..bd7358e86e59b --- /dev/null +++ b/compiler-rt/lib/rtsan/CMakeLists.txt @@ -0,0 +1,92 @@ +include_directories(..) + +set(RTSAN_CXX_SOURCES + rtsan.cpp + rtsan_context.cpp + rtsan_stack.cpp + rtsan_interceptors.cpp) + +set(RTSAN_PREINIT_SOURCES + rtsan_preinit.cpp) + +set(RTSAN_HEADERS + rtsan.h + rtsan_context.h + rtsan_stack.h) + +set(RTSAN_DEPS) + +set(RTSAN_CFLAGS + ${COMPILER_RT_COMMON_CFLAGS} + ${COMPILER_RT_CXX_CFLAGS} + -DSANITIZER_COMMON_NO_REDEFINE_BUILTINS) +set(RTSAN_LINK_FLAGS ${COMPILER_RT_COMMON_LINK_FLAGS}) +set(RTSAN_LINK_LIBS + ${COMPILER_RT_UNWINDER_LINK_LIBS} + ${COMPILER_RT_CXX_LINK_LIBS}) + +if(APPLE) + add_compiler_rt_object_libraries(RTRtsan + OS ${SANITIZER_COMMON_SUPPORTED_OS} + ARCHS ${RTSAN_SUPPORTED_ARCH} + SOURCES ${RTSAN_CXX_SOURCES} + ADDITIONAL_HEADERS ${RTSAN_HEADERS} + CFLAGS ${RTSAN_CFLAGS} + DEPS ${RTSAN_DEPS}) +else() + add_compiler_rt_object_libraries(RTRtsan + ARCHS ${RTSAN_SUPPORTED_ARCH} + SOURCES ${RTSAN_CXX_SOURCES} + ADDITIONAL_HEADERS ${RTSAN_HEADERS} + CFLAGS ${RTSAN_CFLAGS} + DEPS ${RTSAN_DEPS}) + add_compiler_rt_object_libraries(RTRtsan_preinit + ARCHS ${RTSAN_SUPPORTED_ARCH} + SOURCES ${RTSAN_PREINIT_SOURCES} + ADDITIONAL_HEADERS ${RTSAN_HEADERS} + CFLAGS ${RTSAN_CFLAGS}) +endif() + +set(RTSAN_COMMON_RUNTIME_OBJECT_LIBS + RTInterception + RTSanitizerCommon + RTSanitizerCommonLibc + RTSanitizerCommonCoverage + RTSanitizerCommonSymbolizer) + +append_list_if(COMPILER_RT_HAS_LIBDL dl RTSAN_LINK_LIBS) +append_list_if(COMPILER_RT_HAS_LIBRT rt RTSAN_LINK_LIBS) +append_list_if(COMPILER_RT_HAS_LIBM m RTSAN_LINK_LIBS) +append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread RTSAN_LINK_LIBS) +append_list_if(COMPILER_RT_HAS_LIBLOG log RTSAN_LINK_LIBS) + +add_compiler_rt_component(rtsan) + +if (APPLE) + add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS) + set(RTSAN_LINK_FLAGS ${RTSAN_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}) + + add_compiler_rt_runtime(clang_rt.rtsan + SHARED + OS ${SANITIZER_COMMON_SUPPORTED_OS} + ARCHS ${RTSAN_SUPPORTED_ARCH} + OBJECT_LIBS RTRtsan + ${RTSAN_COMMON_RUNTIME_OBJECT_LIBS} + LINK_FLAGS ${RTSAN_LINK_FLAGS} + LINK_LIBS ${RTSAN_LINK_LIBS} + PARENT_TARGET rtsan) +else() + add_compiler_rt_runtime(clang_rt.rtsan + STATIC + ARCHS ${RTSAN_SUPPORTED_ARCH} + OBJECT_LIBS RTRtsan_preinit + RTRtsan + ${RTSAN_COMMON_RUNTIME_OBJECT_LIBS} + LINK_FLAGS ${RTSAN_LINK_FLAGS} + CFLAGS ${RTSAN_CFLAGS} + PARENT_TARGET rtsan) +endif() + +if(COMPILER_RT_INCLUDE_TESTS) + add_subdirectory(tests) +endif() diff --git a/compiler-rt/lib/rtsan/rtsan.cpp b/compiler-rt/lib/rtsan/rtsan.cpp new file mode 100644 index 0000000000000..43a63b4636f1e --- /dev/null +++ b/compiler-rt/lib/rtsan/rtsan.cpp @@ -0,0 +1,37 @@ +//===--- rtsan.cpp - Realtime Sanitizer -------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#include +#include +#include + +extern "C" { + +SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init() { + __rtsan::InitializeInterceptors(); +} + +SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_realtime_enter() { + __rtsan::GetContextForThisThread().RealtimePush(); +} + +SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_realtime_exit() { + __rtsan::GetContextForThisThread().RealtimePop(); +} + +SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_off() { + __rtsan::GetContextForThisThread().BypassPush(); +} + +SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_on() { + __rtsan::GetContextForThisThread().BypassPop(); +} + +} // extern "C" diff --git a/compiler-rt/lib/rtsan/rtsan.h b/compiler-rt/lib/rtsan/rtsan.h new file mode 100644 index 0000000000000..8b1219c13cbd3 --- /dev/null +++ b/compiler-rt/lib/rtsan/rtsan.h @@ -0,0 +1,40 @@ +//===--- rtsan.h - Realtime Sanitizer ---------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "sanitizer_common/sanitizer_internal_defs.h" + +extern "C" { + +// Initialise rtsan interceptors. +// A call to this method is added to the preinit array on Linux systems. +SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init(); + +// Enter real-time context. +// When in a real-time context, RTSan interceptors will error if realtime +// violations are detected. Calls to this method are injected at the code +// generation stage when RTSan is enabled. +SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_realtime_enter(); + +// Exit the real-time context. +// When not in a real-time context, RTSan interceptors will simply forward +// intercepted method calls to the real methods. +SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_realtime_exit(); + +// Disable all RTSan error reporting. +// Injected into the code if "nosanitize(realtime)" is on a function. +SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_off(); + +// Re-enable all RTSan error reporting. +// The counterpart to `__rtsan_off`. +SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_on(); + +} // extern "C" diff --git a/compiler-rt/lib/radsan/radsan_context.cpp b/compiler-rt/lib/rtsan/rtsan_context.cpp similarity index 63% rename from compiler-rt/lib/radsan/radsan_context.cpp rename to compiler-rt/lib/rtsan/rtsan_context.cpp index cb7a2e75c632d..9eba3fb0ec25a 100644 --- a/compiler-rt/lib/radsan/radsan_context.cpp +++ b/compiler-rt/lib/rtsan/rtsan_context.cpp @@ -1,14 +1,16 @@ -/** - This file is part of the RealtimeSanitizer (RADSan) project. - https://github.com/realtime-sanitizer/radsan +//===--- rtsan_context.cpp - Realtime Sanitizer -----------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// - Copyright 2023 David Trevelyan & Alistair Barker - Subject to GNU General Public License (GPL) v3.0 -*/ - -#include +#include -#include +#include #include #include @@ -23,18 +25,18 @@ static pthread_once_t key_once = PTHREAD_ONCE_INIT; static void internalFree(void *ptr) { __sanitizer::InternalFree(ptr); } -static __radsan::Context &GetContextForThisThreadImpl() { +static __rtsan::Context &GetContextForThisThreadImpl() { auto make_thread_local_context_key = []() { CHECK_EQ(pthread_key_create(&context_key, internalFree), 0); }; pthread_once(&key_once, make_thread_local_context_key); - __radsan::Context *current_thread_context = - static_cast<__radsan::Context *>(pthread_getspecific(context_key)); + __rtsan::Context *current_thread_context = + static_cast<__rtsan::Context *>(pthread_getspecific(context_key)); if (current_thread_context == nullptr) { - current_thread_context = static_cast<__radsan::Context *>( - __sanitizer::InternalAlloc(sizeof(__radsan::Context))); - new (current_thread_context) __radsan::Context(); + current_thread_context = static_cast<__rtsan::Context *>( + __sanitizer::InternalAlloc(sizeof(__rtsan::Context))); + new (current_thread_context) __rtsan::Context(); pthread_setspecific(context_key, current_thread_context); } @@ -43,9 +45,9 @@ static __radsan::Context &GetContextForThisThreadImpl() { /* This is a placeholder stub for a future feature that will allow - a user to configure RADSan's behaviour when a real-time safety - violation is detected. The RADSan developers intend for the - following choices to be made available, via a RADSAN_OPTIONS + a user to configure RTSan's behaviour when a real-time safety + violation is detected. The RTSan developers intend for the + following choices to be made available, via a RTSAN_OPTIONS environment variable, in a future PR: i) exit, @@ -57,7 +59,7 @@ static __radsan::Context &GetContextForThisThreadImpl() { */ static void InvokeViolationDetectedAction() { exit(EXIT_FAILURE); } -namespace __radsan { +namespace __rtsan { Context::Context() = default; @@ -87,9 +89,9 @@ void Context::PrintDiagnostics(const char *intercepted_function_name) { "Real-time violation: intercepted call to real-time unsafe function " "`%s` in real-time context! Stack trace:\n", intercepted_function_name); - __radsan::PrintStackTrace(); + __rtsan::PrintStackTrace(); } Context &GetContextForThisThread() { return GetContextForThisThreadImpl(); } -} // namespace __radsan +} // namespace __rtsan diff --git a/compiler-rt/lib/rtsan/rtsan_context.h b/compiler-rt/lib/rtsan/rtsan_context.h new file mode 100644 index 0000000000000..515bb8ade1eb9 --- /dev/null +++ b/compiler-rt/lib/rtsan/rtsan_context.h @@ -0,0 +1,38 @@ +//===--- rtsan_context.h - Realtime Sanitizer -------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#pragma once + +namespace __rtsan { + +class Context { +public: + Context(); + + void RealtimePush(); + void RealtimePop(); + + void BypassPush(); + void BypassPop(); + + void ExpectNotRealtime(const char *intercepted_function_name); + +private: + bool InRealtimeContext() const; + bool IsBypassed() const; + void PrintDiagnostics(const char *intercepted_function_name); + + int realtime_depth{0}; + int bypass_depth{0}; +}; + +Context &GetContextForThisThread(); + +} // namespace __rtsan diff --git a/compiler-rt/lib/radsan/radsan_interceptors.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp similarity index 78% rename from compiler-rt/lib/radsan/radsan_interceptors.cpp rename to compiler-rt/lib/rtsan/rtsan_interceptors.cpp index 0a4b7d3a349b0..adcad6c5de412 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp @@ -1,5 +1,4 @@ -//===--- radsan_interceptors.cpp - Realtime Sanitizer --------------*- C++ -//-*-===// +//===--- rtsan_interceptors.cpp - Realtime Sanitizer ------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,16 +8,16 @@ // //===----------------------------------------------------------------------===// -#include "radsan/radsan_interceptors.h" +#include "rtsan/rtsan_interceptors.h" #include "sanitizer_common/sanitizer_platform.h" #include "sanitizer_common/sanitizer_platform_interceptors.h" #include "interception/interception.h" -#include "radsan/radsan_context.h" +#include "rtsan/rtsan_context.h" #if !SANITIZER_LINUX && !SANITIZER_APPLE -#error Sorry, radsan does not yet support this platform +#error Sorry, rtsan does not yet support this platform #endif #if SANITIZER_APPLE @@ -40,18 +39,18 @@ using namespace __sanitizer; -namespace __radsan { +namespace __rtsan { void ExpectNotRealtime(const char *intercepted_function_name) { GetContextForThisThread().ExpectNotRealtime(intercepted_function_name); } -} // namespace __radsan +} // namespace __rtsan // Filesystem INTERCEPTOR(int, open, const char *path, int oflag, ...) { // TODO Establish whether we should intercept here if the flag contains // O_NONBLOCK - __radsan::ExpectNotRealtime("open"); + __rtsan::ExpectNotRealtime("open"); va_list args; va_start(args, oflag); @@ -65,7 +64,7 @@ INTERCEPTOR(int, open, const char *path, int oflag, ...) { INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) { // TODO Establish whether we should intercept here if the flag contains // O_NONBLOCK - __radsan::ExpectNotRealtime("openat"); + __rtsan::ExpectNotRealtime("openat"); va_list args; va_start(args, oflag); @@ -79,13 +78,13 @@ INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) { INTERCEPTOR(int, creat, const char *path, mode_t mode) { // TODO Establish whether we should intercept here if the flag contains // O_NONBLOCK - __radsan::ExpectNotRealtime("creat"); - auto result = REAL(creat)(path, mode); + __rtsan::ExpectNotRealtime("creat"); + const int result = REAL(creat)(path, mode); return result; } INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) { - __radsan::ExpectNotRealtime("fcntl"); + __rtsan::ExpectNotRealtime("fcntl"); va_list args; va_start(args, cmd); @@ -106,40 +105,40 @@ INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) { } INTERCEPTOR(int, close, int filedes) { - __radsan::ExpectNotRealtime("close"); + __rtsan::ExpectNotRealtime("close"); return REAL(close)(filedes); } INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) { - __radsan::ExpectNotRealtime("fopen"); + __rtsan::ExpectNotRealtime("fopen"); return REAL(fopen)(path, mode); } INTERCEPTOR(size_t, fread, void *ptr, size_t size, size_t nitems, FILE *stream) { - __radsan::ExpectNotRealtime("fread"); + __rtsan::ExpectNotRealtime("fread"); return REAL(fread)(ptr, size, nitems, stream); } INTERCEPTOR(size_t, fwrite, const void *ptr, size_t size, size_t nitems, FILE *stream) { - __radsan::ExpectNotRealtime("fwrite"); + __rtsan::ExpectNotRealtime("fwrite"); return REAL(fwrite)(ptr, size, nitems, stream); } INTERCEPTOR(int, fclose, FILE *stream) { - __radsan::ExpectNotRealtime("fclose"); + __rtsan::ExpectNotRealtime("fclose"); return REAL(fclose)(stream); } INTERCEPTOR(int, fputs, const char *s, FILE *stream) { - __radsan::ExpectNotRealtime("fputs"); + __rtsan::ExpectNotRealtime("fputs"); return REAL(fputs)(s, stream); } // Streams INTERCEPTOR(int, puts, const char *s) { - __radsan::ExpectNotRealtime("puts"); + __rtsan::ExpectNotRealtime("puts"); return REAL(puts)(s); } @@ -149,207 +148,207 @@ INTERCEPTOR(int, puts, const char *s) { // OSSpinLockLock is deprecated, but still in use in libc++ #pragma clang diagnostic ignored "-Wdeprecated-declarations" INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) { - __radsan::ExpectNotRealtime("OSSpinLockLock"); + __rtsan::ExpectNotRealtime("OSSpinLockLock"); return REAL(OSSpinLockLock)(lock); } #pragma clang diagnostic pop INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) { - __radsan::ExpectNotRealtime("os_unfair_lock_lock"); + __rtsan::ExpectNotRealtime("os_unfair_lock_lock"); return REAL(os_unfair_lock_lock)(lock); } #elif SANITIZER_LINUX INTERCEPTOR(int, pthread_spin_lock, pthread_spinlock_t *spinlock) { - __radsan::ExpectNotRealtime("pthread_spin_lock"); + __rtsan::ExpectNotRealtime("pthread_spin_lock"); return REAL(pthread_spin_lock)(spinlock); } #endif INTERCEPTOR(int, pthread_create, pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { - __radsan::ExpectNotRealtime("pthread_create"); + __rtsan::ExpectNotRealtime("pthread_create"); return REAL(pthread_create)(thread, attr, start_routine, arg); } INTERCEPTOR(int, pthread_mutex_lock, pthread_mutex_t *mutex) { - __radsan::ExpectNotRealtime("pthread_mutex_lock"); + __rtsan::ExpectNotRealtime("pthread_mutex_lock"); return REAL(pthread_mutex_lock)(mutex); } INTERCEPTOR(int, pthread_mutex_unlock, pthread_mutex_t *mutex) { - __radsan::ExpectNotRealtime("pthread_mutex_unlock"); + __rtsan::ExpectNotRealtime("pthread_mutex_unlock"); return REAL(pthread_mutex_unlock)(mutex); } INTERCEPTOR(int, pthread_join, pthread_t thread, void **value_ptr) { - __radsan::ExpectNotRealtime("pthread_join"); + __rtsan::ExpectNotRealtime("pthread_join"); return REAL(pthread_join)(thread, value_ptr); } INTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *cond) { - __radsan::ExpectNotRealtime("pthread_cond_signal"); + __rtsan::ExpectNotRealtime("pthread_cond_signal"); return REAL(pthread_cond_signal)(cond); } INTERCEPTOR(int, pthread_cond_broadcast, pthread_cond_t *cond) { - __radsan::ExpectNotRealtime("pthread_cond_broadcast"); + __rtsan::ExpectNotRealtime("pthread_cond_broadcast"); return REAL(pthread_cond_broadcast)(cond); } INTERCEPTOR(int, pthread_cond_wait, pthread_cond_t *cond, pthread_mutex_t *mutex) { - __radsan::ExpectNotRealtime("pthread_cond_wait"); + __rtsan::ExpectNotRealtime("pthread_cond_wait"); return REAL(pthread_cond_wait)(cond, mutex); } INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *cond, pthread_mutex_t *mutex, const timespec *ts) { - __radsan::ExpectNotRealtime("pthread_cond_timedwait"); + __rtsan::ExpectNotRealtime("pthread_cond_timedwait"); return REAL(pthread_cond_timedwait)(cond, mutex, ts); } INTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *lock) { - __radsan::ExpectNotRealtime("pthread_rwlock_rdlock"); + __rtsan::ExpectNotRealtime("pthread_rwlock_rdlock"); return REAL(pthread_rwlock_rdlock)(lock); } INTERCEPTOR(int, pthread_rwlock_unlock, pthread_rwlock_t *lock) { - __radsan::ExpectNotRealtime("pthread_rwlock_unlock"); + __rtsan::ExpectNotRealtime("pthread_rwlock_unlock"); return REAL(pthread_rwlock_unlock)(lock); } INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) { - __radsan::ExpectNotRealtime("pthread_rwlock_wrlock"); + __rtsan::ExpectNotRealtime("pthread_rwlock_wrlock"); return REAL(pthread_rwlock_wrlock)(lock); } // Sleeping INTERCEPTOR(unsigned int, sleep, unsigned int s) { - __radsan::ExpectNotRealtime("sleep"); + __rtsan::ExpectNotRealtime("sleep"); return REAL(sleep)(s); } INTERCEPTOR(int, usleep, useconds_t u) { - __radsan::ExpectNotRealtime("usleep"); + __rtsan::ExpectNotRealtime("usleep"); return REAL(usleep)(u); } INTERCEPTOR(int, nanosleep, const struct timespec *rqtp, struct timespec *rmtp) { - __radsan::ExpectNotRealtime("nanosleep"); + __rtsan::ExpectNotRealtime("nanosleep"); return REAL(nanosleep)(rqtp, rmtp); } // Memory INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) { - __radsan::ExpectNotRealtime("calloc"); + __rtsan::ExpectNotRealtime("calloc"); return REAL(calloc)(num, size); } INTERCEPTOR(void, free, void *ptr) { if (ptr != NULL) { - __radsan::ExpectNotRealtime("free"); + __rtsan::ExpectNotRealtime("free"); } return REAL(free)(ptr); } INTERCEPTOR(void *, malloc, SIZE_T size) { - __radsan::ExpectNotRealtime("malloc"); + __rtsan::ExpectNotRealtime("malloc"); return REAL(malloc)(size); } INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) { - __radsan::ExpectNotRealtime("realloc"); + __rtsan::ExpectNotRealtime("realloc"); return REAL(realloc)(ptr, size); } INTERCEPTOR(void *, reallocf, void *ptr, SIZE_T size) { - __radsan::ExpectNotRealtime("reallocf"); + __rtsan::ExpectNotRealtime("reallocf"); return REAL(reallocf)(ptr, size); } INTERCEPTOR(void *, valloc, SIZE_T size) { - __radsan::ExpectNotRealtime("valloc"); + __rtsan::ExpectNotRealtime("valloc"); return REAL(valloc)(size); } #if SANITIZER_INTERCEPT_ALIGNED_ALLOC INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) { - __radsan::ExpectNotRealtime("aligned_alloc"); + __rtsan::ExpectNotRealtime("aligned_alloc"); return REAL(aligned_alloc)(alignment, size); } -#define RADSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc) +#define RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc) #else -#define RADSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC +#define RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC #endif INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) { - __radsan::ExpectNotRealtime("posix_memalign"); + __rtsan::ExpectNotRealtime("posix_memalign"); return REAL(posix_memalign)(memptr, alignment, size); } #if SANITIZER_INTERCEPT_MEMALIGN INTERCEPTOR(void *, memalign, size_t alignment, size_t size) { - __radsan::ExpectNotRealtime("memalign"); + __rtsan::ExpectNotRealtime("memalign"); return REAL(memalign)(alignment, size); } #endif #if SANITIZER_INTERCEPT_PVALLOC INTERCEPTOR(void *, pvalloc, size_t size) { - __radsan::ExpectNotRealtime("pvalloc"); + __rtsan::ExpectNotRealtime("pvalloc"); return REAL(pvalloc)(size); } #endif // Sockets INTERCEPTOR(int, socket, int domain, int type, int protocol) { - __radsan::ExpectNotRealtime("socket"); + __rtsan::ExpectNotRealtime("socket"); return REAL(socket)(domain, type, protocol); } INTERCEPTOR(ssize_t, send, int sockfd, const void *buf, size_t len, int flags) { - __radsan::ExpectNotRealtime("send"); + __rtsan::ExpectNotRealtime("send"); return REAL(send)(sockfd, buf, len, flags); } INTERCEPTOR(ssize_t, sendmsg, int socket, const struct msghdr *message, int flags) { - __radsan::ExpectNotRealtime("sendmsg"); + __rtsan::ExpectNotRealtime("sendmsg"); return REAL(sendmsg)(socket, message, flags); } INTERCEPTOR(ssize_t, sendto, int socket, const void *buffer, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len) { - __radsan::ExpectNotRealtime("sendto"); + __rtsan::ExpectNotRealtime("sendto"); return REAL(sendto)(socket, buffer, length, flags, dest_addr, dest_len); } INTERCEPTOR(ssize_t, recv, int socket, void *buffer, size_t length, int flags) { - __radsan::ExpectNotRealtime("recv"); + __rtsan::ExpectNotRealtime("recv"); return REAL(recv)(socket, buffer, length, flags); } INTERCEPTOR(ssize_t, recvfrom, int socket, void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len) { - __radsan::ExpectNotRealtime("recvfrom"); + __rtsan::ExpectNotRealtime("recvfrom"); return REAL(recvfrom)(socket, buffer, length, flags, address, address_len); } INTERCEPTOR(ssize_t, recvmsg, int socket, struct msghdr *message, int flags) { - __radsan::ExpectNotRealtime("recvmsg"); + __rtsan::ExpectNotRealtime("recvmsg"); return REAL(recvmsg)(socket, message, flags); } INTERCEPTOR(int, shutdown, int socket, int how) { - __radsan::ExpectNotRealtime("shutdown"); + __rtsan::ExpectNotRealtime("shutdown"); return REAL(shutdown)(socket, how); } // Preinit -namespace __radsan { +namespace __rtsan { void InitializeInterceptors() { INTERCEPT_FUNCTION(calloc); INTERCEPT_FUNCTION(free); @@ -357,7 +356,7 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(realloc); INTERCEPT_FUNCTION(reallocf); INTERCEPT_FUNCTION(valloc); - RADSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC; + RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC; INTERCEPT_FUNCTION(posix_memalign); #if SANITIZER_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign); @@ -410,4 +409,4 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(recvfrom); INTERCEPT_FUNCTION(shutdown); } -} // namespace __radsan +} // namespace __rtsan diff --git a/compiler-rt/lib/radsan/radsan_interceptors.h b/compiler-rt/lib/rtsan/rtsan_interceptors.h similarity index 76% rename from compiler-rt/lib/radsan/radsan_interceptors.h rename to compiler-rt/lib/rtsan/rtsan_interceptors.h index 95dd44ca5bc80..a3dac27544c66 100644 --- a/compiler-rt/lib/radsan/radsan_interceptors.h +++ b/compiler-rt/lib/rtsan/rtsan_interceptors.h @@ -1,5 +1,4 @@ -//===--- radsan_interceptors.h - Realtime Sanitizer --------------*- C++ -//-*-===// +//===--- rtsan_interceptors.h - Realtime Sanitizer --------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,6 +10,6 @@ #pragma once -namespace __radsan { +namespace __rtsan { void InitializeInterceptors(); -} // namespace __radsan +} // namespace __rtsan diff --git a/compiler-rt/lib/rtsan/rtsan_preinit.cpp b/compiler-rt/lib/rtsan/rtsan_preinit.cpp new file mode 100644 index 0000000000000..8cea61c3ea8b7 --- /dev/null +++ b/compiler-rt/lib/rtsan/rtsan_preinit.cpp @@ -0,0 +1,23 @@ +//===--- rtsan_preinit.cpp - Realtime Sanitizer -----------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_internal_defs.h" +#include + +#if SANITIZER_CAN_USE_PREINIT_ARRAY + +// The symbol is called __local_rtsan_preinit, because it's not intended to be +// exported. +// This code is linked into the main executable when -fsanitize=realtime is in +// the link flags. It can only use exported interface functions. +__attribute__((section(".preinit_array"), + used)) void (*__local_rtsan_preinit)(void) = __rtsan_init; + +#endif diff --git a/compiler-rt/lib/radsan/radsan_stack.cpp b/compiler-rt/lib/rtsan/rtsan_stack.cpp similarity index 62% rename from compiler-rt/lib/radsan/radsan_stack.cpp rename to compiler-rt/lib/rtsan/rtsan_stack.cpp index debd9777f5dbc..ff0af8fe675f3 100644 --- a/compiler-rt/lib/radsan/radsan_stack.cpp +++ b/compiler-rt/lib/rtsan/rtsan_stack.cpp @@ -1,12 +1,14 @@ -/** - This file is part of the RealtimeSanitizer (RADSan) project. - https://github.com/realtime-sanitizer/radsan - - Copyright 2023 David Trevelyan & Alistair Barker - Subject to GNU General Public License (GPL) v3.0 -*/ - -#include "radsan_stack.h" +//===--- rtsan_stack.cpp - Realtime Sanitizer -------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#include "rtsan_stack.h" #include #include @@ -31,12 +33,12 @@ static void SetGlobalStackTraceFormat() { CommonFlags cf; cf.CopyFrom(*common_flags()); cf.stack_trace_format = "DEFAULT"; - cf.external_symbolizer_path = GetEnv("RADSAN_SYMBOLIZER_PATH"); + cf.external_symbolizer_path = GetEnv("RTSAN_SYMBOLIZER_PATH"); OverrideCommonFlags(cf); } -using namespace __radsan; -void __radsan::PrintStackTrace() { +using namespace __rtsan; +void __rtsan::PrintStackTrace() { BufferedStackTrace stack{}; diff --git a/compiler-rt/lib/rtsan/rtsan_stack.h b/compiler-rt/lib/rtsan/rtsan_stack.h new file mode 100644 index 0000000000000..cecdd43045db5 --- /dev/null +++ b/compiler-rt/lib/rtsan/rtsan_stack.h @@ -0,0 +1,15 @@ +//===--- rtsan_stack.h - Realtime Sanitizer ---------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#pragma once + +namespace __rtsan { +void PrintStackTrace(); +} // namespace __rtsan diff --git a/compiler-rt/lib/rtsan/tests/CMakeLists.txt b/compiler-rt/lib/rtsan/tests/CMakeLists.txt new file mode 100644 index 0000000000000..87a5730685376 --- /dev/null +++ b/compiler-rt/lib/rtsan/tests/CMakeLists.txt @@ -0,0 +1,103 @@ +include(CompilerRTCompile) + +include_directories(..) + +set(RTSAN_UNITTEST_CFLAGS + ${COMPILER_RT_UNITTEST_CFLAGS} + ${COMPILER_RT_GTEST_CFLAGS} + ${COMPILER_RT_GMOCK_CFLAGS} + ${SANITIZER_TEST_CXX_CFLAGS} + -I${COMPILER_RT_SOURCE_DIR}/lib/ + -I${COMPILER_RT_SOURCE_DIR}/include/ + -I${COMPILER_RT_SOURCE_DIR}/lib/rtsan + -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests + -DSANITIZER_COMMON_NO_REDEFINE_BUILTINS + -O2) + +set(RTSAN_INST_TEST_SOURCES + rtsan_test_functional.cpp + rtsan_test_interceptors.cpp + rtsan_test_main.cpp) + +set(RTSAN_NOINST_TEST_SOURCES + ../rtsan_preinit.cpp + rtsan_test_context.cpp + rtsan_test_main.cpp) + +set(RTSAN_UNITTEST_HEADERS + rtsan_test_utilities.h) + +add_custom_target(RtsanUnitTests) +set_target_properties(RtsanUnitTests PROPERTIES FOLDER "Compiler-RT Tests") + +set(RTSAN_UNITTEST_LINK_FLAGS + ${COMPILER_RT_UNITTEST_LINK_FLAGS} + ${COMPILER_RT_UNWINDER_LINK_LIBS} + ${SANITIZER_TEST_CXX_LIBRARIES} + -no-pie) + +if (APPLE) + add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS) + list(APPEND RTSAN_UNITTEST_LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}) + list(APPEND RTSAN_UNITTEST_LINK_FLAGS ${DARWIN_osx_LINK_FLAGS}) + list(APPEND RTSAN_UNITTEST_CFLAGS ${DARWIN_osx_CFLAGS}) +else() + list(APPEND RTSAN_UNITTEST_LINK_FLAGS -latomic) +endif() + +set(COMPILER_RT_GOOGLETEST_SOURCES ${COMPILER_RT_GTEST_SOURCE} ${COMPILER_RT_GMOCK_SOURCE}) + +set(RTSAN_TEST_ARCH ${RTSAN_SUPPORTED_ARCH}) +if(APPLE) + darwin_filter_host_archs(RTSAN_SUPPORTED_ARCH RTSAN_TEST_ARCH) +endif() + +foreach(arch ${RTSAN_TEST_ARCH}) + set(RtsanTestObjects) + generate_compiler_rt_tests(RtsanTestObjects + RtsanUnitTests "Rtsan-${arch}-Test" ${arch} + COMPILE_DEPS ${RTSAN_UNITTEST_HEADERS} + SOURCES ${RTSAN_INST_TEST_SOURCES} ${COMPILER_RT_GOOGLETEST_SOURCES} + DEPS llvm_gtest rtsan + CFLAGS ${RTSAN_UNITTEST_CFLAGS} -fsanitize=realtime + LINK_FLAGS ${RTSAN_UNITTEST_LINK_FLAGS} -fsanitize=realtime) + set_target_properties(RtsanUnitTests PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + + set(RTSAN_TEST_RUNTIME RTRtsanTest.${arch}) + if(APPLE) + set(RTSAN_TEST_RUNTIME_OBJECTS + $ + $ + $ + $ + $ + $) + else() + set(RTSAN_TEST_RUNTIME_OBJECTS + $ + $ + $ + $ + $ + $ + $) + endif() + add_library(${RTSAN_TEST_RUNTIME} STATIC ${RTSAN_TEST_RUNTIME_OBJECTS}) + set_target_properties(${RTSAN_TEST_RUNTIME} PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + FOLDER "Compiler-RT Runtime tests") + + set(RtsanNoInstTestObjects) + generate_compiler_rt_tests(RtsanNoInstTestObjects + RtsanUnitTests "Rtsan-${arch}-NoInstTest" ${arch} + COMPILE_DEPS ${RTSAN_UNITTEST_HEADERS} + SOURCES ${RTSAN_NOINST_TEST_SOURCES} + ${COMPILER_RT_GOOGLETEST_SOURCES} + DEPS llvm_gtest + CFLAGS ${RTSAN_UNITTEST_CFLAGS} + LINK_FLAGS ${RTSAN_UNITTEST_LINK_FLAGS} + RUNTIME ${RTSAN_TEST_RUNTIME}) + set_target_properties(RtsanUnitTests PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +endforeach() diff --git a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_context.cpp similarity index 64% rename from compiler-rt/lib/radsan/tests/radsan_test_context.cpp rename to compiler-rt/lib/rtsan/tests/rtsan_test_context.cpp index 1c098fcabd2ad..b7e73236a14cc 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_context.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_context.cpp @@ -1,5 +1,4 @@ -//===--- radsan_test_context.cpp - Realtime Sanitizer --------------*- C++ -//-*-===// +//===--- rtsan_test_context.cpp - Realtime Sanitizer ------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,34 +8,34 @@ // //===----------------------------------------------------------------------===// -#include "radsan_test_utilities.h" +#include "rtsan_test_utilities.h" -#include "radsan_context.h" +#include "rtsan_context.h" -TEST(TestRadsanContext, CanCreateContext) { __radsan::Context context{}; } +TEST(TestRtsanContext, CanCreateContext) { __rtsan::Context context{}; } -TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieBeforeRealtimePush) { - __radsan::Context context{}; +TEST(TestRtsanContext, ExpectNotRealtimeDoesNotDieBeforeRealtimePush) { + __rtsan::Context context{}; context.ExpectNotRealtime("do_some_stuff"); } -TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterPushAndPop) { - __radsan::Context context{}; +TEST(TestRtsanContext, ExpectNotRealtimeDoesNotDieAfterPushAndPop) { + __rtsan::Context context{}; context.RealtimePush(); context.RealtimePop(); context.ExpectNotRealtime("do_some_stuff"); } -TEST(TestRadsanContext, ExpectNotRealtimeDiesAfterRealtimePush) { - __radsan::Context context{}; +TEST(TestRtsanContext, ExpectNotRealtimeDiesAfterRealtimePush) { + __rtsan::Context context{}; context.RealtimePush(); EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), ""); } -TEST(TestRadsanContext, +TEST(TestRtsanContext, ExpectNotRealtimeDiesAfterRealtimeAfterMorePushesThanPops) { - __radsan::Context context{}; + __rtsan::Context context{}; context.RealtimePush(); context.RealtimePush(); @@ -46,17 +45,17 @@ TEST(TestRadsanContext, EXPECT_DEATH(context.ExpectNotRealtime("do_some_stuff"), ""); } -TEST(TestRadsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) { - __radsan::Context context{}; +TEST(TestRtsanContext, ExpectNotRealtimeDoesNotDieAfterBypassPush) { + __rtsan::Context context{}; context.RealtimePush(); context.BypassPush(); context.ExpectNotRealtime("do_some_stuff"); } -TEST(TestRadsanContext, +TEST(TestRtsanContext, ExpectNotRealtimeDoesNotDieIfBypassDepthIsGreaterThanZero) { - __radsan::Context context{}; + __rtsan::Context context{}; context.RealtimePush(); context.BypassPush(); diff --git a/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_functional.cpp similarity index 58% rename from compiler-rt/lib/radsan/tests/radsan_test_functional.cpp rename to compiler-rt/lib/rtsan/tests/rtsan_test_functional.cpp index 7c5e85bc45768..2f3cd3a8bd287 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_functional.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_functional.cpp @@ -1,4 +1,4 @@ -//===--- radsan_test.cpp - Realtime Sanitizer --------------*- C++ -*-===// +//===--- rtsan_test.cpp - Realtime Sanitizer --------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,14 +8,14 @@ // // Introduces basic functional tests for the realtime sanitizer. // Not meant to be exhaustive, testing all interceptors, please see -// test_radsan_interceptors.cpp for those tests. +// test_rtsan_interceptors.cpp for those tests. // //===----------------------------------------------------------------------===// #include "gtest/gtest.h" -#include "radsan_test_utilities.h" -#include +#include "rtsan_test_utilities.h" +#include #include #include @@ -34,13 +34,13 @@ #define SI_MAC_DEPLOYMENT_AT_LEAST_10_12 0 #endif -#define RADSAN_TEST_SHARED_MUTEX (!(SI_MAC) || SI_MAC_DEPLOYMENT_AT_LEAST_10_12) +#define RTSAN_TEST_SHARED_MUTEX (!(SI_MAC) || SI_MAC_DEPLOYMENT_AT_LEAST_10_12) using namespace testing; -using namespace radsan_testing; +using namespace rtsan_testing; using namespace std::chrono_literals; -TEST(TestRadsan, VectorPushBackAllocationDiesWhenRealtime) { +TEST(TestRtsan, VectorPushBackAllocationDiesWhenRealtime) { std::vector vec{}; auto Func = [&vec]() { vec.push_back(0.4f); }; ExpectRealtimeDeath(Func); @@ -49,7 +49,7 @@ TEST(TestRadsan, VectorPushBackAllocationDiesWhenRealtime) { ASSERT_EQ(1u, vec.size()); } -TEST(TestRadsan, DestructionOfObjectOnHeapDiesWhenRealtime) { +TEST(TestRtsan, DestructionOfObjectOnHeapDiesWhenRealtime) { auto allocated_ptr = std::make_unique>(); auto Func = [&allocated_ptr]() { allocated_ptr.reset(); }; ExpectRealtimeDeath(Func); @@ -58,34 +58,34 @@ TEST(TestRadsan, DestructionOfObjectOnHeapDiesWhenRealtime) { ASSERT_EQ(nullptr, allocated_ptr.get()); } -TEST(TestRadsan, sleepingAThreadDiesWhenRealtime) { - auto func = []() { std::this_thread::sleep_for(1us); }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); +TEST(TestRtsan, SleepingAThreadDiesWhenRealtime) { + auto Func = []() { std::this_thread::sleep_for(1us); }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, ifstreamCreationDiesWhenRealtime) { - auto func = []() { std::ifstream ifs{"./file.txt"}; }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); +TEST(TestRtsan, IfstreamCreationDiesWhenRealtime) { + auto Func = []() { std::ifstream ifs{"./file.txt"}; }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); std::remove("./file.txt"); } -TEST(TestRadsan, ofstreamCreationDiesWhenRealtime) { - auto func = []() { std::ofstream ofs{"./file.txt"}; }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); +TEST(TestRtsan, OfstreamCreationDiesWhenRealtime) { + auto Func = []() { std::ofstream ofs{"./file.txt"}; }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); std::remove("./file.txt"); } -TEST(TestRadsan, LockingAMutexDiesWhenRealtime) { +TEST(TestRtsan, LockingAMutexDiesWhenRealtime) { std::mutex mutex{}; auto Func = [&]() { mutex.lock(); }; ExpectRealtimeDeath(Func); ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, UnlockingAMutexDiesWhenRealtime) { +TEST(TestRtsan, UnlockingAMutexDiesWhenRealtime) { std::mutex mutex{}; mutex.lock(); auto Func = [&]() { mutex.unlock(); }; @@ -93,16 +93,16 @@ TEST(TestRadsan, UnlockingAMutexDiesWhenRealtime) { ExpectNonRealtimeSurvival(Func); } -#if RADSAN_TEST_SHARED_MUTEX +#if RTSAN_TEST_SHARED_MUTEX -TEST(TestRadsan, LockingASharedMutexDiesWhenRealtime) { +TEST(TestRtsan, LockingASharedMutexDiesWhenRealtime) { std::shared_mutex mutex{}; auto Func = [&]() { mutex.lock(); }; ExpectRealtimeDeath(Func); ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, UnlockingASharedMutexDiesWhenRealtime) { +TEST(TestRtsan, UnlockingASharedMutexDiesWhenRealtime) { std::shared_mutex mutex{}; mutex.lock(); auto Func = [&]() { mutex.unlock(); }; @@ -110,14 +110,14 @@ TEST(TestRadsan, UnlockingASharedMutexDiesWhenRealtime) { ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, SharedLockingASharedMutexDiesWhenRealtime) { +TEST(TestRtsan, SharedLockingASharedMutexDiesWhenRealtime) { std::shared_mutex mutex{}; auto Func = [&]() { mutex.lock_shared(); }; ExpectRealtimeDeath(Func); ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, SharedUnlockingASharedMutexDiesWhenRealtime) { +TEST(TestRtsan, SharedUnlockingASharedMutexDiesWhenRealtime) { std::shared_mutex mutex{}; mutex.lock_shared(); auto Func = [&]() { mutex.unlock_shared(); }; @@ -125,22 +125,22 @@ TEST(TestRadsan, SharedUnlockingASharedMutexDiesWhenRealtime) { ExpectNonRealtimeSurvival(Func); } -#endif // RADSAN_TEST_SHARED_MUTEX +#endif // RTSAN_TEST_SHARED_MUTEX -TEST(TestRadsan, launchingAThreadDiesWhenRealtime) { - auto func = [&]() { +TEST(TestRtsan, LaunchingAThreadDiesWhenRealtime) { + auto Func = [&]() { std::thread Thread{[]() {}}; Thread.join(); }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); } namespace { void InvokeStdFunction(std::function &&function) { function(); } } // namespace -TEST(TestRadsan, CopyingALambdaWithLargeCaptureDiesWhenRealtime) { +TEST(TestRtsan, CopyingALambdaWithLargeCaptureDiesWhenRealtime) { std::array lots_of_data{}; auto lambda = [lots_of_data]() mutable { // Stop everything getting optimised out @@ -148,12 +148,12 @@ TEST(TestRadsan, CopyingALambdaWithLargeCaptureDiesWhenRealtime) { EXPECT_EQ(16, lots_of_data.size()); EXPECT_EQ(0.25f, lots_of_data[3]); }; - auto func = [&]() { invokeStdFunction(lambda); }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); + auto Func = [&]() { InvokeStdFunction(lambda); }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, AccessingALargeAtomicVariableDiesWhenRealtime) { +TEST(TestRtsan, AccessingALargeAtomicVariableDiesWhenRealtime) { std::atomic small_atomic{0.0f}; ASSERT_TRUE(small_atomic.is_lock_free()); RealtimeInvoke([&small_atomic]() { float x = small_atomic.load(); }); @@ -165,43 +165,43 @@ TEST(TestRadsan, AccessingALargeAtomicVariableDiesWhenRealtime) { ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, firstCoutDiesWhenRealtime) { - auto func = []() { std::cout << "Hello, world!" << std::endl; }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); +TEST(TestRtsan, FirstCoutDiesWhenRealtime) { + auto Func = []() { std::cout << "Hello, world!" << std::endl; }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, secondCoutDiesWhenRealtime) { +TEST(TestRtsan, SecondCoutDiesWhenRealtime) { std::cout << "Hello, world"; - auto func = []() { std::cout << "Hello, again!" << std::endl; }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); + auto Func = []() { std::cout << "Hello, again!" << std::endl; }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, printfDiesWhenRealtime) { - auto func = []() { printf("Hello, world!\n"); }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); +TEST(TestRtsan, PrintfDiesWhenRealtime) { + auto Func = []() { printf("Hello, world!\n"); }; + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, throwingAnExceptionDiesWhenRealtime) { - auto func = [&]() { +TEST(TestRtsan, ThrowingAnExceptionDiesWhenRealtime) { + auto Func = [&]() { try { throw std::exception(); } catch (std::exception &) { } }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); + ExpectRealtimeDeath(Func); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsan, DoesNotDieIfTurnedOff) { +TEST(TestRtsan, DoesNotDieIfTurnedOff) { std::mutex mutex{}; auto RealtimeUnsafeFunc = [&]() { - __radsan_off(); + __rtsan_off(); mutex.lock(); mutex.unlock(); - __radsan_on(); + __rtsan_on(); }; - RealtimeInvoke(realtime_unsafe_func); + RealtimeInvoke(RealtimeUnsafeFunc); } diff --git a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors.cpp similarity index 57% rename from compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp rename to compiler-rt/lib/rtsan/tests/rtsan_test_interceptors.cpp index 942d1b33b9078..f5b016089087d 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_interceptors.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors.cpp @@ -1,5 +1,4 @@ -//===--- radsan_test_interceptors.cpp - Realtime Sanitizer --------------*- C++ -//-*-===// +//===--- rtsan_test_interceptors.cpp - Realtime Sanitizer -------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,7 +13,7 @@ #include #include -#include "radsan_test_utilities.h" +#include "rtsan_test_utilities.h" #if SANITIZER_APPLE #include @@ -36,36 +35,17 @@ #include using namespace testing; -using namespace radsan_testing; +using namespace rtsan_testing; using namespace std::chrono_literals; void *FakeThreadEntryPoint(void *) { return nullptr; } -class RadsanFileTest : public ::testing::Test { +class RtsanFileTest : public ::testing::Test { protected: void SetUp() override { const ::testing::TestInfo *const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - file_path = std::string("/tmp/radsan_temporary_test_file_") + - test_info->name() + ".txt"; - } - - // Gets a file path with the test's name in in - // This file will be removed if it exists at the end of the test - const char *GetTemporaryFilePath() const { return file_path.c_str(); } - - void TearDown() override { std::remove(GetTemporaryFilePath()); } - -private: - std::string file_path; -}; - -class RadsanFileTest : public ::testing::Test { -protected: - void SetUp() override { - const ::testing::TestInfo *const test_info = - ::testing::UnitTest::GetInstance()->current_test_info(); - file_path_ = std::string("/tmp/radsan_temporary_test_file_") + + file_path_ = std::string("/tmp/rtsan_temporary_test_file_") + test_info->name() + ".txt"; RemoveTemporaryFile(); } @@ -85,81 +65,81 @@ class RadsanFileTest : public ::testing::Test { Allocation and deallocation */ -TEST(TestRadsanInterceptors, MallocDiesWhenRealtime) { +TEST(TestRtsanInterceptors, MallocDiesWhenRealtime) { auto Func = []() { EXPECT_NE(nullptr, malloc(1)); }; - expectRealtimeDeath(Func, "malloc"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "malloc"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, ReallocDiesWhenRealtime) { +TEST(TestRtsanInterceptors, ReallocDiesWhenRealtime) { void *ptr_1 = malloc(1); auto Func = [ptr_1]() { EXPECT_NE(nullptr, realloc(ptr_1, 8)); }; - expectRealtimeDeath(Func, "realloc"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "realloc"); + ExpectNonRealtimeSurvival(Func); } #if SANITIZER_APPLE -TEST(TestRadsanInterceptors, ReallocfDiesWhenRealtime) { +TEST(TestRtsanInterceptors, ReallocfDiesWhenRealtime) { void *ptr_1 = malloc(1); auto Func = [ptr_1]() { EXPECT_NE(nullptr, reallocf(ptr_1, 8)); }; - expectRealtimeDeath(Func, "reallocf"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "reallocf"); + ExpectNonRealtimeSurvival(Func); } #endif -TEST(TestRadsanInterceptors, VallocDiesWhenRealtime) { +TEST(TestRtsanInterceptors, VallocDiesWhenRealtime) { auto Func = []() { EXPECT_NE(nullptr, valloc(4)); }; - expectRealtimeDeath(Func, "valloc"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "valloc"); + ExpectNonRealtimeSurvival(Func); } #if SANITIZER_INTERCEPT_ALIGNED_ALLOC -TEST(TestRadsanInterceptors, AlignedAllocDiesWhenRealtime) { +TEST(TestRtsanInterceptors, AlignedAllocDiesWhenRealtime) { auto Func = []() { EXPECT_NE(nullptr, aligned_alloc(16, 32)); }; - expectRealtimeDeath(Func, "aligned_alloc"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "aligned_alloc"); + ExpectNonRealtimeSurvival(Func); } #endif // free_sized and free_aligned_sized (both C23) are not yet supported -TEST(TestRadsanInterceptors, FreeDiesWhenRealtime) { +TEST(TestRtsanInterceptors, FreeDiesWhenRealtime) { void *ptr_1 = malloc(1); void *ptr_2 = malloc(1); - expectRealtimeDeath([ptr_1]() { free(ptr_1); }, "free"); - expectNonrealtimeSurvival([ptr_2]() { free(ptr_2); }); + ExpectRealtimeDeath([ptr_1]() { free(ptr_1); }, "free"); + ExpectNonRealtimeSurvival([ptr_2]() { free(ptr_2); }); // Prevent malloc/free pair being optimised out ASSERT_NE(nullptr, ptr_1); ASSERT_NE(nullptr, ptr_2); } -TEST(TestRadsanInterceptors, FreeSurvivesWhenRealtimeIfArgumentIsNull) { +TEST(TestRtsanInterceptors, FreeSurvivesWhenRealtimeIfArgumentIsNull) { RealtimeInvoke([]() { free(NULL); }); - expectNonrealtimeSurvival([]() { free(NULL); }); + ExpectNonRealtimeSurvival([]() { free(NULL); }); } -TEST(TestRadsanInterceptors, PosixMemalignDiesWhenRealtime) { +TEST(TestRtsanInterceptors, PosixMemalignDiesWhenRealtime) { auto Func = []() { void *ptr; posix_memalign(&ptr, 4, 4); }; - expectRealtimeDeath(Func, "posix_memalign"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "posix_memalign"); + ExpectNonRealtimeSurvival(Func); } #if SANITIZER_INTERCEPT_MEMALIGN -TEST(TestRadsanInterceptors, MemalignDiesWhenRealtime) { +TEST(TestRtsanInterceptors, MemalignDiesWhenRealtime) { auto Func = []() { EXPECT_NE(memalign(2, 2048), nullptr); }; - expectRealtimeDeath(Func, "memalign"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "memalign"); + ExpectNonRealtimeSurvival(Func); } #endif #if SANITIZER_INTERCEPT_PVALLOC -TEST(TestRadsanInterceptors, PvallocDiesWhenRealtime) { +TEST(TestRtsanInterceptors, PvallocDiesWhenRealtime) { auto Func = []() { EXPECT_NE(pvalloc(2048), nullptr); }; - expectRealtimeDeath(Func, "pvalloc"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "pvalloc"); + ExpectNonRealtimeSurvival(Func); } #endif @@ -167,44 +147,44 @@ TEST(TestRadsanInterceptors, PvallocDiesWhenRealtime) { Sleeping */ -TEST(TestRadsanInterceptors, SleepDiesWhenRealtime) { +TEST(TestRtsanInterceptors, SleepDiesWhenRealtime) { auto Func = []() { sleep(0u); }; - expectRealtimeDeath(Func, "sleep"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "sleep"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, UsleepDiesWhenRealtime) { +TEST(TestRtsanInterceptors, UsleepDiesWhenRealtime) { auto Func = []() { usleep(1u); }; - expectRealtimeDeath(Func, "usleep"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "usleep"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, NanosleepDiesWhenRealtime) { +TEST(TestRtsanInterceptors, NanosleepDiesWhenRealtime) { auto Func = []() { timespec T{}; nanosleep(&T, &T); }; - expectRealtimeDeath(Func, "nanosleep"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "nanosleep"); + ExpectNonRealtimeSurvival(Func); } /* Filesystem */ -TEST_F(RadsanFileTest, OpenDiesWhenRealtime) { +TEST_F(RtsanFileTest, OpenDiesWhenRealtime) { auto func = [this]() { open(GetTemporaryFilePath(), O_RDONLY); }; ExpectRealtimeDeath(func, "open"); ExpectNonRealtimeSurvival(func); } -TEST_F(RadsanFileTest, OpenatDiesWhenRealtime) { +TEST_F(RtsanFileTest, OpenatDiesWhenRealtime) { auto func = [this]() { openat(0, GetTemporaryFilePath(), O_RDONLY); }; ExpectRealtimeDeath(func, "openat"); ExpectNonRealtimeSurvival(func); } -TEST_F(RadsanFileTest, OpenCreatesFileWithProperMode) { +TEST_F(RtsanFileTest, OpenCreatesFileWithProperMode) { const int mode = S_IRGRP | S_IROTH | S_IRUSR | S_IWUSR; const int fd = open(GetTemporaryFilePath(), O_CREAT | O_WRONLY, mode); @@ -218,19 +198,19 @@ TEST_F(RadsanFileTest, OpenCreatesFileWithProperMode) { ASSERT_THAT(st.st_mode & 0777, Eq(mode)); } -TEST_F(RadsanFileTest, CreatDiesWhenRealtime) { +TEST_F(RtsanFileTest, CreatDiesWhenRealtime) { auto func = [this]() { creat(GetTemporaryFilePath(), S_IWOTH | S_IROTH); }; ExpectRealtimeDeath(func, "creat"); ExpectNonRealtimeSurvival(func); } -TEST(TestRadsanInterceptors, FcntlDiesWhenRealtime) { +TEST(TestRtsanInterceptors, FcntlDiesWhenRealtime) { auto func = []() { fcntl(0, F_GETFL); }; ExpectRealtimeDeath(func, "fcntl"); ExpectNonRealtimeSurvival(func); } -TEST_F(RadsanFileTest, FcntlFlockDiesWhenRealtime) { +TEST_F(RtsanFileTest, FcntlFlockDiesWhenRealtime) { int fd = creat(GetTemporaryFilePath(), S_IRUSR | S_IWUSR); ASSERT_THAT(fd, Ne(-1)); @@ -251,7 +231,7 @@ TEST_F(RadsanFileTest, FcntlFlockDiesWhenRealtime) { close(fd); } -TEST_F(RadsanFileTest, FcntlSetFdDiesWhenRealtime) { +TEST_F(RtsanFileTest, FcntlSetFdDiesWhenRealtime) { int fd = creat(GetTemporaryFilePath(), S_IRUSR | S_IWUSR); ASSERT_THAT(fd, Ne(-1)); @@ -273,13 +253,13 @@ TEST_F(RadsanFileTest, FcntlSetFdDiesWhenRealtime) { close(fd); } -TEST(TestRadsanInterceptors, CloseDiesWhenRealtime) { +TEST(TestRtsanInterceptors, CloseDiesWhenRealtime) { auto func = []() { close(0); }; ExpectRealtimeDeath(func, "close"); ExpectNonRealtimeSurvival(func); } -TEST_F(RadsanFileTest, FopenDiesWhenRealtime) { +TEST_F(RtsanFileTest, FopenDiesWhenRealtime) { auto func = [this]() { auto fd = fopen(GetTemporaryFilePath(), "w"); EXPECT_THAT(fd, Ne(nullptr)); @@ -288,7 +268,7 @@ TEST_F(RadsanFileTest, FopenDiesWhenRealtime) { ExpectNonRealtimeSurvival(func); } -TEST_F(RadsanFileTest, FreadDiesWhenRealtime) { +TEST_F(RtsanFileTest, FreadDiesWhenRealtime) { auto fd = fopen(GetTemporaryFilePath(), "w"); auto func = [fd]() { char c{}; @@ -300,7 +280,7 @@ TEST_F(RadsanFileTest, FreadDiesWhenRealtime) { fclose(fd); } -TEST_F(RadsanFileTest, FwriteDiesWhenRealtime) { +TEST_F(RtsanFileTest, FwriteDiesWhenRealtime) { auto fd = fopen(GetTemporaryFilePath(), "w"); ASSERT_NE(nullptr, fd); auto message = "Hello, world!"; @@ -309,7 +289,7 @@ TEST_F(RadsanFileTest, FwriteDiesWhenRealtime) { ExpectNonRealtimeSurvival(func); } -TEST_F(RadsanFileTest, FcloseDiesWhenRealtime) { +TEST_F(RtsanFileTest, FcloseDiesWhenRealtime) { auto fd = fopen(GetTemporaryFilePath(), "w"); EXPECT_THAT(fd, Ne(nullptr)); auto func = [fd]() { fclose(fd); }; @@ -317,13 +297,13 @@ TEST_F(RadsanFileTest, FcloseDiesWhenRealtime) { ExpectNonRealtimeSurvival(func); } -TEST(TestRadsanInterceptors, PutsDiesWhenRealtime) { +TEST(TestRtsanInterceptors, PutsDiesWhenRealtime) { auto func = []() { puts("Hello, world!\n"); }; - expectRealtimeDeath(func); - expectNonrealtimeSurvival(func); + ExpectRealtimeDeath(func); + ExpectNonRealtimeSurvival(func); } -TEST_F(RadsanFileTest, FputsDiesWhenRealtime) { +TEST_F(RtsanFileTest, FputsDiesWhenRealtime) { auto fd = fopen(GetTemporaryFilePath(), "w"); ASSERT_THAT(fd, Ne(nullptr)) << errno; auto func = [fd]() { fputs("Hello, world!\n", fd); }; @@ -337,45 +317,45 @@ TEST_F(RadsanFileTest, FputsDiesWhenRealtime) { Concurrency */ -TEST(TestRadsanInterceptors, PthreadCreateDiesWhenRealtime) { +TEST(TestRtsanInterceptors, PthreadCreateDiesWhenRealtime) { auto Func = []() { pthread_t thread{}; const pthread_attr_t attr{}; struct thread_info *thread_info; pthread_create(&thread, &attr, &FakeThreadEntryPoint, thread_info); }; - expectRealtimeDeath(Func, "pthread_create"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "pthread_create"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, PthreadMutexLockDiesWhenRealtime) { +TEST(TestRtsanInterceptors, PthreadMutexLockDiesWhenRealtime) { auto Func = []() { pthread_mutex_t mutex{}; pthread_mutex_lock(&mutex); }; - expectRealtimeDeath(Func, "pthread_mutex_lock"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "pthread_mutex_lock"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, PthreadMutexUnlockDiesWhenRealtime) { +TEST(TestRtsanInterceptors, PthreadMutexUnlockDiesWhenRealtime) { auto Func = []() { pthread_mutex_t mutex{}; pthread_mutex_unlock(&mutex); }; - expectRealtimeDeath(Func, "pthread_mutex_unlock"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "pthread_mutex_unlock"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, PthreadMutexJoinDiesWhenRealtime) { +TEST(TestRtsanInterceptors, PthreadMutexJoinDiesWhenRealtime) { auto Func = []() { pthread_t thread{}; pthread_join(thread, nullptr); }; - expectRealtimeDeath(Func, "pthread_join"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "pthread_join"); + ExpectNonRealtimeSurvival(Func); } #if SANITIZER_APPLE @@ -383,66 +363,66 @@ TEST(TestRadsanInterceptors, PthreadMutexJoinDiesWhenRealtime) { #pragma clang diagnostic push // OSSpinLockLock is deprecated, but still in use in libc++ #pragma clang diagnostic ignored "-Wdeprecated-declarations" -TEST(TestRadsanInterceptors, OsSpinLockLockDiesWhenRealtime) { +TEST(TestRtsanInterceptors, OsSpinLockLockDiesWhenRealtime) { auto Func = []() { OSSpinLock spin_lock{}; OSSpinLockLock(&spin_lock); }; - expectRealtimeDeath(Func, "OSSpinLockLock"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "OSSpinLockLock"); + ExpectNonRealtimeSurvival(Func); } #pragma clang diagnostic pop -TEST(TestRadsanInterceptors, OsUnfairLockLockDiesWhenRealtime) { +TEST(TestRtsanInterceptors, OsUnfairLockLockDiesWhenRealtime) { auto Func = []() { os_unfair_lock_s unfair_lock{}; os_unfair_lock_lock(&unfair_lock); }; - expectRealtimeDeath(Func, "os_unfair_lock_lock"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "os_unfair_lock_lock"); + ExpectNonRealtimeSurvival(Func); } #endif #if SANITIZER_LINUX -TEST(TestRadsanInterceptors, SpinLockLockDiesWhenRealtime) { +TEST(TestRtsanInterceptors, SpinLockLockDiesWhenRealtime) { pthread_spinlock_t spin_lock; pthread_spin_init(&spin_lock, PTHREAD_PROCESS_SHARED); auto Func = [&]() { pthread_spin_lock(&spin_lock); }; - expectRealtimeDeath(Func, "pthread_spin_lock"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "pthread_spin_lock"); + ExpectNonRealtimeSurvival(Func); } #endif -TEST(TestRadsanInterceptors, PthreadCondSignalDiesWhenRealtime) { +TEST(TestRtsanInterceptors, PthreadCondSignalDiesWhenRealtime) { pthread_cond_t cond{}; pthread_cond_init(&cond, NULL); auto Func = [&cond]() { pthread_cond_signal(&cond); }; - expectRealtimeDeath(Func, "pthread_cond_signal"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "pthread_cond_signal"); + ExpectNonRealtimeSurvival(Func); pthread_cond_destroy(&cond); } -TEST(TestRadsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) { +TEST(TestRtsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) { pthread_cond_t cond{}; pthread_cond_init(&cond, NULL); auto Func = [&cond]() { pthread_cond_broadcast(&cond); }; - expectRealtimeDeath(Func, "pthread_cond_broadcast"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "pthread_cond_broadcast"); + ExpectNonRealtimeSurvival(Func); pthread_cond_destroy(&cond); } -TEST(TestRadsanInterceptors, PthreadCondWaitDiesWhenRealtime) { +TEST(TestRtsanInterceptors, PthreadCondWaitDiesWhenRealtime) { pthread_cond_t cond; pthread_mutex_t mutex; ASSERT_EQ(0, pthread_cond_init(&cond, nullptr)); ASSERT_EQ(0, pthread_mutex_init(&mutex, nullptr)); auto Func = [&]() { pthread_cond_wait(&cond, &mutex); }; - expectRealtimeDeath(Func, "pthread_cond_wait"); + ExpectRealtimeDeath(Func, "pthread_cond_wait"); // It's very difficult to test the success case here without doing some // sleeping, which is at the mercy of the scheduler. What's really important // here is the interception - so we're only testing that for now. @@ -451,86 +431,86 @@ TEST(TestRadsanInterceptors, PthreadCondWaitDiesWhenRealtime) { pthread_mutex_destroy(&mutex); } -TEST(TestRadsanInterceptors, PthreadRwlockRdlockDiesWhenRealtime) { +TEST(TestRtsanInterceptors, PthreadRwlockRdlockDiesWhenRealtime) { auto Func = []() { pthread_rwlock_t rw_lock; pthread_rwlock_rdlock(&rw_lock); }; - expectRealtimeDeath(Func, "pthread_rwlock_rdlock"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "pthread_rwlock_rdlock"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, PthreadRwlockUnlockDiesWhenRealtime) { +TEST(TestRtsanInterceptors, PthreadRwlockUnlockDiesWhenRealtime) { auto Func = []() { pthread_rwlock_t rw_lock; pthread_rwlock_unlock(&rw_lock); }; - expectRealtimeDeath(Func, "pthread_rwlock_unlock"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "pthread_rwlock_unlock"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, PthreadRwlockWrlockDiesWhenRealtime) { +TEST(TestRtsanInterceptors, PthreadRwlockWrlockDiesWhenRealtime) { auto Func = []() { pthread_rwlock_t rw_lock; pthread_rwlock_wrlock(&rw_lock); }; - expectRealtimeDeath(Func, "pthread_rwlock_wrlock"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "pthread_rwlock_wrlock"); + ExpectNonRealtimeSurvival(Func); } /* Sockets */ -TEST(TestRadsanInterceptors, OpeningASocketDiesWhenRealtime) { +TEST(TestRtsanInterceptors, OpeningASocketDiesWhenRealtime) { auto Func = []() { socket(PF_INET, SOCK_STREAM, 0); }; - expectRealtimeDeath(Func, "socket"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "socket"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, SendToASocketDiesWhenRealtime) { +TEST(TestRtsanInterceptors, SendToASocketDiesWhenRealtime) { auto Func = []() { send(0, nullptr, 0, 0); }; - expectRealtimeDeath(Func, "send"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "send"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, SendmsgToASocketDiesWhenRealtime) { +TEST(TestRtsanInterceptors, SendmsgToASocketDiesWhenRealtime) { msghdr msg{}; auto Func = [&]() { sendmsg(0, &msg, 0); }; - expectRealtimeDeath(Func, "sendmsg"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "sendmsg"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, SendtoToASocketDiesWhenRealtime) { +TEST(TestRtsanInterceptors, SendtoToASocketDiesWhenRealtime) { sockaddr addr{}; socklen_t len{}; auto Func = [&]() { sendto(0, nullptr, 0, 0, &addr, len); }; - expectRealtimeDeath(Func, "sendto"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "sendto"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, RecvFromASocketDiesWhenRealtime) { +TEST(TestRtsanInterceptors, RecvFromASocketDiesWhenRealtime) { auto Func = []() { recv(0, nullptr, 0, 0); }; - expectRealtimeDeath(Func, "recv"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "recv"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, RecvfromOnASocketDiesWhenRealtime) { +TEST(TestRtsanInterceptors, RecvfromOnASocketDiesWhenRealtime) { sockaddr addr{}; socklen_t len{}; auto Func = [&]() { recvfrom(0, nullptr, 0, 0, &addr, &len); }; - expectRealtimeDeath(Func, "recvfrom"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "recvfrom"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, RecvmsgOnASocketDiesWhenRealtime) { +TEST(TestRtsanInterceptors, RecvmsgOnASocketDiesWhenRealtime) { msghdr msg{}; auto Func = [&]() { recvmsg(0, &msg, 0); }; - expectRealtimeDeath(Func, "recvmsg"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "recvmsg"); + ExpectNonRealtimeSurvival(Func); } -TEST(TestRadsanInterceptors, ShutdownOnASocketDiesWhenRealtime) { +TEST(TestRtsanInterceptors, ShutdownOnASocketDiesWhenRealtime) { auto Func = [&]() { shutdown(0, 0); }; - expectRealtimeDeath(Func, "shutdown"); - expectNonrealtimeSurvival(Func); + ExpectRealtimeDeath(Func, "shutdown"); + ExpectNonRealtimeSurvival(Func); } diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_main.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_main.cpp new file mode 100644 index 0000000000000..255ac9497103e --- /dev/null +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_main.cpp @@ -0,0 +1,17 @@ +//===--- rtsan_test_main.cpp - Realtime Sanitizer ---------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#include "sanitizer_test_utils.h" + +int main(int argc, char **argv) { + testing::GTEST_FLAG(death_test_style) = "threadsafe"; + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h b/compiler-rt/lib/rtsan/tests/rtsan_test_utilities.h similarity index 85% rename from compiler-rt/lib/radsan/tests/radsan_test_utilities.h rename to compiler-rt/lib/rtsan/tests/rtsan_test_utilities.h index 068f8805d5b85..d24182ff7ef59 100644 --- a/compiler-rt/lib/radsan/tests/radsan_test_utilities.h +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_utilities.h @@ -1,5 +1,4 @@ -//===--- radsan_test_utilities.h - Realtime Sanitizer --------------*- C++ -//-*-===// +//===--- rtsan_test_utilities.h - Realtime Sanitizer ------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,16 +10,16 @@ #pragma once -#include "radsan.h" +#include "rtsan.h" #include "gmock/gmock.h" #include -namespace radsan_testing { +namespace rtsan_testing { template void RealtimeInvoke(Function &&Func) { - __radsan_realtime_enter(); + __rtsan_realtime_enter(); std::forward(Func)(); - __radsan_realtime_exit(); + __rtsan_realtime_exit(); } template @@ -45,4 +44,4 @@ template void expectNonrealtimeSurvival(Function &&Func) { std::forward(Func)(); } -} // namespace radsan_testing +} // namespace rtsan_testing diff --git a/compiler-rt/test/radsan/CMakeLists.txt b/compiler-rt/test/radsan/CMakeLists.txt deleted file mode 100644 index d6b8dc9652879..0000000000000 --- a/compiler-rt/test/radsan/CMakeLists.txt +++ /dev/null @@ -1,58 +0,0 @@ - - - - -###### -# TODO: Full lit tests coming in a future review when we introduce the codegen -###### - - - - -set(RADSAN_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) - -set(RADSAN_TESTSUITES) -set(RADSAN_FDR_TESTSUITES) - -set(RADSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) -set(RADSAN_FDR_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) -set(RADSAN_TEST_ARCH ${RADSAN_SUPPORTED_ARCH}) -if(APPLE) - darwin_filter_host_archs(RADSAN_SUPPORTED_ARCH RADSAN_TEST_ARCH) -endif() - -if (COMPILER_RT_HAS_RADSAN) - foreach(arch ${RADSAN_TEST_ARCH}) - set(RADSAN_TEST_TARGET_ARCH ${arch}) - string(TOLOWER "-${arch}-${OS_NAME}" RADSAN_TEST_CONFIG_SUFFIX) - get_test_cc_for_arch(${arch} RADSAN_TEST_TARGET_CC RADSAN_TEST_TARGET_CFLAGS) - string(TOUPPER ${arch} ARCH_UPPER_CASE) - set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config) - - configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in - ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg.py) - list(APPEND RADSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}) - endforeach() -endif() - -if(COMPILER_RT_INCLUDE_TESTS) - configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in - ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py) - if(COMPILER_RT_RADSAN_HAS_STATIC_RUNTIME) - configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in - ${CMAKE_CURRENT_BINARY_DIR}/Unit/dynamic/lit.site.cfg.py) - endif() - list(APPEND RADSAN_TEST_DEPS RadsanUnitTests) - list(APPEND RADSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit) - if(COMPILER_RT_RADSAN_HAS_STATIC_RUNTIME) - list(APPEND RADSAN_DYNAMIC_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit/dynamic) - endif() -endif() - -add_lit_testsuite(check-radsan "Running the Radsan tests" - ${RADSAN_TESTSUITES} - DEPENDS ${RADSAN_TEST_DEPS}) -set_target_properties(check-radsan PROPERTIES FOLDER "Compiler-RT Misc") diff --git a/compiler-rt/test/rtsan/CMakeLists.txt b/compiler-rt/test/rtsan/CMakeLists.txt new file mode 100644 index 0000000000000..ba1070467f1a3 --- /dev/null +++ b/compiler-rt/test/rtsan/CMakeLists.txt @@ -0,0 +1,58 @@ + + + + +###### +# TODO: Full lit tests coming in a future review when we introduce the codegen +###### + + + + +set(RTSAN_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + +set(RTSAN_TESTSUITES) +set(RTSAN_FDR_TESTSUITES) + +set(RTSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) +set(RTSAN_FDR_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) +set(RTSAN_TEST_ARCH ${RTSAN_SUPPORTED_ARCH}) +if(APPLE) + darwin_filter_host_archs(RTSAN_SUPPORTED_ARCH RTSAN_TEST_ARCH) +endif() + +if (COMPILER_RT_HAS_RTSAN) + foreach(arch ${RTSAN_TEST_ARCH}) + set(RTSAN_TEST_TARGET_ARCH ${arch}) + string(TOLOWER "-${arch}-${OS_NAME}" RTSAN_TEST_CONFIG_SUFFIX) + get_test_cc_for_arch(${arch} RTSAN_TEST_TARGET_CC RTSAN_TEST_TARGET_CFLAGS) + string(TOUPPER ${arch} ARCH_UPPER_CASE) + set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config) + + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in + ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg.py) + list(APPEND RTSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}) + endforeach() +endif() + +if(COMPILER_RT_INCLUDE_TESTS) + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in + ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py) + if(COMPILER_RT_RTSAN_HAS_STATIC_RUNTIME) + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in + ${CMAKE_CURRENT_BINARY_DIR}/Unit/dynamic/lit.site.cfg.py) + endif() + list(APPEND RTSAN_TEST_DEPS RtsanUnitTests) + list(APPEND RTSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit) + if(COMPILER_RT_RTSAN_HAS_STATIC_RUNTIME) + list(APPEND RTSAN_DYNAMIC_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit/dynamic) + endif() +endif() + +add_lit_testsuite(check-rtsan "Running the Rtsan tests" + ${RTSAN_TESTSUITES} + DEPENDS ${RTSAN_TEST_DEPS}) +set_target_properties(check-rtsan PROPERTIES FOLDER "Compiler-RT Misc") diff --git a/compiler-rt/test/radsan/Unit/lit.site.cfg.py.in b/compiler-rt/test/rtsan/Unit/lit.site.cfg.py.in similarity index 65% rename from compiler-rt/test/radsan/Unit/lit.site.cfg.py.in rename to compiler-rt/test/rtsan/Unit/lit.site.cfg.py.in index 432e0ed5e1907..59e1e10360b52 100644 --- a/compiler-rt/test/radsan/Unit/lit.site.cfg.py.in +++ b/compiler-rt/test/rtsan/Unit/lit.site.cfg.py.in @@ -9,7 +9,7 @@ config.name = 'RealtimeSanitizer-Unit' # Setup test source and exec root. For unit tests, we define # it as build directory with ASan unit tests. # FIXME: De-hardcode this path. -config.test_exec_root = "@COMPILER_RT_BINARY_DIR@/lib/radsan/tests" +config.test_exec_root = "@COMPILER_RT_BINARY_DIR@/lib/rtsan/tests" config.test_source_root = config.test_exec_root if not config.parallelism_group: @@ -17,9 +17,9 @@ if not config.parallelism_group: if config.host_os == 'Darwin': # On Darwin, we default to ignore_noninstrumented_modules=1, which also - # suppresses some races the tests are supposed to find. See radsan/lit.cfg.py. - if 'RADSAN_OPTIONS' in config.environment: - config.environment['RADSAN_OPTIONS'] += ':ignore_noninstrumented_modules=0' + # suppresses some races the tests are supposed to find. See rtsan/lit.cfg.py. + if 'RTSAN_OPTIONS' in config.environment: + config.environment['RTSAN_OPTIONS'] += ':ignore_noninstrumented_modules=0' else: - config.environment['RADSAN_OPTIONS'] = 'ignore_noninstrumented_modules=0' - config.environment['RADSAN_OPTIONS'] += ':ignore_interceptors_accesses=0' + config.environment['RTSAN_OPTIONS'] = 'ignore_noninstrumented_modules=0' + config.environment['RTSAN_OPTIONS'] += ':ignore_interceptors_accesses=0' diff --git a/compiler-rt/test/radsan/lit.cfg.py b/compiler-rt/test/rtsan/lit.cfg.py similarity index 64% rename from compiler-rt/test/radsan/lit.cfg.py rename to compiler-rt/test/rtsan/lit.cfg.py index b9e4dbc03abb6..137a7d99495ec 100644 --- a/compiler-rt/test/radsan/lit.cfg.py +++ b/compiler-rt/test/rtsan/lit.cfg.py @@ -1,31 +1,31 @@ import os # Setup config name. -config.name = "RADSAN" + config.name_suffix +config.name = "RTSAN" + config.name_suffix # Setup source root. config.test_source_root = os.path.dirname(__file__) -# Setup default compiler flags use with -fradsan-instrument option. -clang_radsan_cflags = ["-fradsan-instrument", config.target_cflags] +# Setup default compiler flags use with -frtsan-instrument option. +clang_rtsan_cflags = ["-frtsan-instrument", config.target_cflags] -# If libc++ was used to build radsan libraries, libc++ is needed. Fix applied +# If libc++ was used to build rtsan libraries, libc++ is needed. Fix applied # to Linux only since -rpath may not be portable. This can be extended to # other platforms. if config.libcxx_used == "1" and config.host_os == "Linux": - clang_radsan_cflags = clang_radsan_cflags + ( + clang_rtsan_cflags = clang_rtsan_cflags + ( ["-L%s -lc++ -Wl,-rpath=%s" % (config.llvm_shlib_dir, config.llvm_shlib_dir)] ) -clang_radsan_cxxflags = config.cxx_mode_flags + clang_radsan_cflags +clang_rtsan_cxxflags = config.cxx_mode_flags + clang_rtsan_cflags def build_invocation(compile_flags): return " " + " ".join([config.clang] + compile_flags) + " " -# Assume that llvm-radsan is in the config.llvm_tools_dir. -llvm_radsan = os.path.join(config.llvm_tools_dir, "llvm-radsan") +# Assume that llvm-rtsan is in the config.llvm_tools_dir. +llvm_rtsan = os.path.join(config.llvm_tools_dir, "llvm-rtsan") # Setup substitutions. if config.host_os == "Linux": @@ -37,17 +37,17 @@ def build_invocation(compile_flags): config.substitutions.append( ("%clangxx ", build_invocation(config.cxx_mode_flags + [config.target_cflags])) ) -config.substitutions.append(("%clang_radsan ", build_invocation(clang_radsan_cflags))) +config.substitutions.append(("%clang_rtsan ", build_invocation(clang_rtsan_cflags))) config.substitutions.append( - ("%clangxx_radsan", build_invocation(clang_radsan_cxxflags)) + ("%clangxx_rtsan", build_invocation(clang_rtsan_cxxflags)) ) -config.substitutions.append(("%llvm_radsan", llvm_radsan)) +config.substitutions.append(("%llvm_rtsan", llvm_rtsan)) config.substitutions.append( ( - "%radsanlib", + "%rtsanlib", ( "-lm -lpthread %s -lrt -L%s " - "-Wl,-whole-archive -lclang_rt.radsan%s -Wl,-no-whole-archive" + "-Wl,-whole-archive -lclang_rt.rtsan%s -Wl,-no-whole-archive" ) % (libdl_flag, config.compiler_rt_libdir, config.target_suffix), ) diff --git a/compiler-rt/test/radsan/lit.site.cfg.py.in b/compiler-rt/test/rtsan/lit.site.cfg.py.in similarity index 69% rename from compiler-rt/test/radsan/lit.site.cfg.py.in rename to compiler-rt/test/rtsan/lit.site.cfg.py.in index 7d509c9f2eb91..5b458645e94dc 100644 --- a/compiler-rt/test/radsan/lit.site.cfg.py.in +++ b/compiler-rt/test/rtsan/lit.site.cfg.py.in @@ -1,10 +1,10 @@ @LIT_SITE_CFG_IN_HEADER@ # Tool-specific config options. -config.name_suffix = "@RADSAN_TEST_CONFIG_SUFFIX@" -config.radsan_lit_source_dir = "@RADSAN_LIT_SOURCE_DIR@" -config.target_cflags = "@RADSAN_TEST_TARGET_CFLAGS@" -config.target_arch = "@RADSAN_TEST_TARGET_ARCH@" +config.name_suffix = "@RTSAN_TEST_CONFIG_SUFFIX@" +config.rtsan_lit_source_dir = "@RTSAN_LIT_SOURCE_DIR@" +config.target_cflags = "@RTSAN_TEST_TARGET_CFLAGS@" +config.target_arch = "@RTSAN_TEST_TARGET_ARCH@" config.built_with_llvm = ("@COMPILER_RT_STANDALONE_BUILD@" != "TRUE") if config.built_with_llvm: From 84f4b068cda975bdb7405c1a9f368b10d28ad0f3 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Wed, 5 Jun 2024 08:14:52 -0700 Subject: [PATCH 35/47] First working rtsan driver tests --- clang/test/Driver/rtsan.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 clang/test/Driver/rtsan.c diff --git a/clang/test/Driver/rtsan.c b/clang/test/Driver/rtsan.c new file mode 100644 index 0000000000000..efb1970d13f76 --- /dev/null +++ b/clang/test/Driver/rtsan.c @@ -0,0 +1,27 @@ +// RUN: %clang --target=x86_64-apple-darwin -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-DARWIN +// CHECK-RTSAN-X86-64-DARWIN-NOT: unsupported option + +// RUN: %clang --target=x86_64-apple-darwin -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-DARWIN +// CHECK-RTSAN-X86-64-DARWIN-NOT: unsupported option +// RUN: %clang --target=x86_64-apple-macos -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-MACOS +// CHECK-RTSAN-X86-64-MACOS-NOT: unsupported option +// RUN: %clang --target=arm64-apple-macos -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-MACOS +// CHECK-RTSAN-ARM64-MACOS-NOT: unsupported option + +// RUN: %clang --target=arm64-apple-ios-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-IOSSIMULATOR +// CHECK-RTSAN-ARM64-IOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=arm64-apple-watchos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-WATCHOSSIMULATOR +// CHECK-RTSAN-ARM64-WATCHOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=arm64-apple-tvos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-TVOSSIMULATOR +// CHECK-RTSAN-ARM64-TVOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=x86_64-apple-ios-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-IOSSIMULATOR +// CHECK-RTSAN-X86-64-IOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=x86_64-apple-watchos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-WATCHOSSIMULATOR +// CHECK-RTSAN-X86-64-WATCHOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=x86_64-apple-tvos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-TVOSSIMULATOR +// CHECK-RTSAN-X86-64-TVOSSIMULATOR-NOT: unsupported option From 8f671be533c9dca786bddbfebdb93443e515794c Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Wed, 5 Jun 2024 08:28:21 -0700 Subject: [PATCH 36/47] Add linux working test --- clang/test/Driver/rtsan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/test/Driver/rtsan.c b/clang/test/Driver/rtsan.c index efb1970d13f76..374712183f850 100644 --- a/clang/test/Driver/rtsan.c +++ b/clang/test/Driver/rtsan.c @@ -25,3 +25,6 @@ // RUN: %clang --target=x86_64-apple-tvos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-TVOSSIMULATOR // CHECK-RTSAN-X86-64-TVOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-LINUX +// CHECK-RTSAN-X86-64-LINUX-NOT: unsupported option From 107329445db8a121451a605fb5b50b7ee84498a6 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Wed, 5 Jun 2024 08:31:00 -0700 Subject: [PATCH 37/47] Another test for openBSD --- clang/test/Driver/rtsan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/test/Driver/rtsan.c b/clang/test/Driver/rtsan.c index 374712183f850..a335eff8845f5 100644 --- a/clang/test/Driver/rtsan.c +++ b/clang/test/Driver/rtsan.c @@ -28,3 +28,6 @@ // RUN: %clang --target=x86_64-linux-gnu -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-LINUX // CHECK-RTSAN-X86-64-LINUX-NOT: unsupported option + +// RUN: not %clang --target=i386-pc-openbsd -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-OPENBSD +// CHECK-RTSAN-OPENBSD: unsupported option '-fsanitize=realtime' for target 'i386-pc-openbsd' From 3fa642a55d001ee8fe014ee6084479fe0c5207f5 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Wed, 5 Jun 2024 08:44:21 -0700 Subject: [PATCH 38/47] Add feature for realtime sanitizer, add incompatible sanitizers --- clang/include/clang/Basic/Features.def | 1 + clang/lib/Driver/SanitizerArgs.cpp | 5 ++++- clang/test/Driver/rtsan.c | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 53f410d3cb4bd..95064eeccf091 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -103,6 +103,7 @@ FEATURE(memory_sanitizer, FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread)) FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow)) FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo)) +FEATURE(realtime_sanitizer, LangOpts.Sanitize.hasOneOf(SanitizerKind::Realtime)) FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics) FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls) FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns) diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 86825a6ccf7a1..44ea55bc971ae 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -556,7 +556,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, SanitizerKind::Address | SanitizerKind::KernelAddress | SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress), - std::make_pair(SanitizerKind::KCFI, SanitizerKind::Function)}; + std::make_pair(SanitizerKind::KCFI, SanitizerKind::Function), + std::make_pair(SanitizerKind::Realtime, + SanitizerKind::Address | SanitizerKind::Thread ), + }; // Enable toolchain specific default sanitizers if not explicitly disabled. SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove; diff --git a/clang/test/Driver/rtsan.c b/clang/test/Driver/rtsan.c index a335eff8845f5..6a5002ed9c284 100644 --- a/clang/test/Driver/rtsan.c +++ b/clang/test/Driver/rtsan.c @@ -31,3 +31,6 @@ // RUN: not %clang --target=i386-pc-openbsd -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-OPENBSD // CHECK-RTSAN-OPENBSD: unsupported option '-fsanitize=realtime' for target 'i386-pc-openbsd' + +// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-TSAN +// CHECK-REALTIME-TSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=thread' From 62d2149ce8d81a4ef45eac6698d8ee20aafa95fb Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Wed, 5 Jun 2024 08:49:01 -0700 Subject: [PATCH 39/47] More incompatabilities added --- clang/lib/Driver/SanitizerArgs.cpp | 3 ++- clang/test/Driver/rtsan.c | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 44ea55bc971ae..3a742fde356aa 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -558,7 +558,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, SanitizerKind::KernelHWAddress), std::make_pair(SanitizerKind::KCFI, SanitizerKind::Function), std::make_pair(SanitizerKind::Realtime, - SanitizerKind::Address | SanitizerKind::Thread ), + SanitizerKind::Address | SanitizerKind::Thread | + SanitizerKind::Undefined | SanitizerKind::Memory) }; // Enable toolchain specific default sanitizers if not explicitly disabled. SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove; diff --git a/clang/test/Driver/rtsan.c b/clang/test/Driver/rtsan.c index 6a5002ed9c284..4be691b2943c7 100644 --- a/clang/test/Driver/rtsan.c +++ b/clang/test/Driver/rtsan.c @@ -34,3 +34,13 @@ // RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-TSAN // CHECK-REALTIME-TSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=thread' + +// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-ASAN +// CHECK-REALTIME-ASAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=address' + +// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-MSAN +// CHECK-REALTIME-MSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=memory' + +// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-UBSAN +// CHECK-REALTIME-UBSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=undefined' + From 4ddf290905de5450f102eeb323294c91d0c18b41 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Wed, 5 Jun 2024 08:51:48 -0700 Subject: [PATCH 40/47] rtsan tests to fsanitize --- clang/test/Driver/fsanitize.c | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c index db14f6e195c64..d1a3ea9a37066 100644 --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -1038,3 +1038,50 @@ // RUN: not %clang --target=aarch64-none-elf -fsanitize=dataflow %s -### 2>&1 | FileCheck %s -check-prefix=UNSUPPORTED-BAREMETAL // RUN: not %clang --target=arm-arm-none-eabi -fsanitize=shadow-call-stack %s -### 2>&1 | FileCheck %s -check-prefix=UNSUPPORTED-BAREMETAL // UNSUPPORTED-BAREMETAL: unsupported option '-fsanitize={{.*}}' for target + +// RUN: %clang --target=x86_64-apple-darwin -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-DARWIN +// CHECK-RTSAN-X86-64-DARWIN-NOT: unsupported option + +// RUN: %clang --target=x86_64-apple-darwin -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-DARWIN +// CHECK-RTSAN-X86-64-DARWIN-NOT: unsupported option +// RUN: %clang --target=x86_64-apple-macos -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-MACOS +// CHECK-RTSAN-X86-64-MACOS-NOT: unsupported option +// RUN: %clang --target=arm64-apple-macos -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-MACOS +// CHECK-RTSAN-ARM64-MACOS-NOT: unsupported option + +// RUN: %clang --target=arm64-apple-ios-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-IOSSIMULATOR +// CHECK-RTSAN-ARM64-IOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=arm64-apple-watchos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-WATCHOSSIMULATOR +// CHECK-RTSAN-ARM64-WATCHOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=arm64-apple-tvos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-TVOSSIMULATOR +// CHECK-RTSAN-ARM64-TVOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=x86_64-apple-ios-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-IOSSIMULATOR +// CHECK-RTSAN-X86-64-IOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=x86_64-apple-watchos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-WATCHOSSIMULATOR +// CHECK-RTSAN-X86-64-WATCHOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=x86_64-apple-tvos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-TVOSSIMULATOR +// CHECK-RTSAN-X86-64-TVOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-LINUX +// CHECK-RTSAN-X86-64-LINUX-NOT: unsupported option + +// RUN: not %clang --target=i386-pc-openbsd -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-OPENBSD +// CHECK-RTSAN-OPENBSD: unsupported option '-fsanitize=realtime' for target 'i386-pc-openbsd' + +// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-TSAN +// CHECK-REALTIME-TSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=thread' + +// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-ASAN +// CHECK-REALTIME-ASAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=address' + +// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-MSAN +// CHECK-REALTIME-MSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=memory' + +// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-UBSAN +// CHECK-REALTIME-UBSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=undefined' + From 9ab67b2d4e99b15fd5ac92e34582cc02d2081231 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Wed, 5 Jun 2024 08:52:51 -0700 Subject: [PATCH 41/47] Deleted rtsan.c --- clang/test/Driver/rtsan.c | 46 --------------------------------------- 1 file changed, 46 deletions(-) delete mode 100644 clang/test/Driver/rtsan.c diff --git a/clang/test/Driver/rtsan.c b/clang/test/Driver/rtsan.c deleted file mode 100644 index 4be691b2943c7..0000000000000 --- a/clang/test/Driver/rtsan.c +++ /dev/null @@ -1,46 +0,0 @@ -// RUN: %clang --target=x86_64-apple-darwin -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-DARWIN -// CHECK-RTSAN-X86-64-DARWIN-NOT: unsupported option - -// RUN: %clang --target=x86_64-apple-darwin -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-DARWIN -// CHECK-RTSAN-X86-64-DARWIN-NOT: unsupported option -// RUN: %clang --target=x86_64-apple-macos -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-MACOS -// CHECK-RTSAN-X86-64-MACOS-NOT: unsupported option -// RUN: %clang --target=arm64-apple-macos -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-MACOS -// CHECK-RTSAN-ARM64-MACOS-NOT: unsupported option - -// RUN: %clang --target=arm64-apple-ios-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-IOSSIMULATOR -// CHECK-RTSAN-ARM64-IOSSIMULATOR-NOT: unsupported option - -// RUN: %clang --target=arm64-apple-watchos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-WATCHOSSIMULATOR -// CHECK-RTSAN-ARM64-WATCHOSSIMULATOR-NOT: unsupported option - -// RUN: %clang --target=arm64-apple-tvos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-TVOSSIMULATOR -// CHECK-RTSAN-ARM64-TVOSSIMULATOR-NOT: unsupported option - -// RUN: %clang --target=x86_64-apple-ios-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-IOSSIMULATOR -// CHECK-RTSAN-X86-64-IOSSIMULATOR-NOT: unsupported option - -// RUN: %clang --target=x86_64-apple-watchos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-WATCHOSSIMULATOR -// CHECK-RTSAN-X86-64-WATCHOSSIMULATOR-NOT: unsupported option - -// RUN: %clang --target=x86_64-apple-tvos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-TVOSSIMULATOR -// CHECK-RTSAN-X86-64-TVOSSIMULATOR-NOT: unsupported option - -// RUN: %clang --target=x86_64-linux-gnu -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-LINUX -// CHECK-RTSAN-X86-64-LINUX-NOT: unsupported option - -// RUN: not %clang --target=i386-pc-openbsd -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-OPENBSD -// CHECK-RTSAN-OPENBSD: unsupported option '-fsanitize=realtime' for target 'i386-pc-openbsd' - -// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-TSAN -// CHECK-REALTIME-TSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=thread' - -// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-ASAN -// CHECK-REALTIME-ASAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=address' - -// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-MSAN -// CHECK-REALTIME-MSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=memory' - -// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-UBSAN -// CHECK-REALTIME-UBSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=undefined' - From 89c0f83f433376b96fa3cd0106ec0df3eaacfd87 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Wed, 5 Jun 2024 08:54:27 -0700 Subject: [PATCH 42/47] Code formatting --- clang/lib/Driver/SanitizerArgs.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 3a742fde356aa..543b7b315423e 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -552,15 +552,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, SanitizerKind::Leak | SanitizerKind::Thread | SanitizerKind::Memory | SanitizerKind::KernelAddress | SanitizerKind::Scudo | SanitizerKind::SafeStack), - std::make_pair(SanitizerKind::MemTag, - SanitizerKind::Address | SanitizerKind::KernelAddress | - SanitizerKind::HWAddress | - SanitizerKind::KernelHWAddress), + std::make_pair(SanitizerKind::MemTag, SanitizerKind::Address | + SanitizerKind::KernelAddress | + SanitizerKind::HWAddress | + SanitizerKind::KernelHWAddress), std::make_pair(SanitizerKind::KCFI, SanitizerKind::Function), std::make_pair(SanitizerKind::Realtime, - SanitizerKind::Address | SanitizerKind::Thread | - SanitizerKind::Undefined | SanitizerKind::Memory) - }; + SanitizerKind::Address | SanitizerKind::Thread | + SanitizerKind::Undefined | SanitizerKind::Memory)}; // Enable toolchain specific default sanitizers if not explicitly disabled. SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove; From 8bb9fd379747810ec73a91b502f7c0813890841f Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Wed, 26 Jun 2024 10:36:29 -0700 Subject: [PATCH 43/47] Fix python styling --- compiler-rt/test/rtsan/lit.cfg.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler-rt/test/rtsan/lit.cfg.py b/compiler-rt/test/rtsan/lit.cfg.py index 137a7d99495ec..7ecefa11aca29 100644 --- a/compiler-rt/test/rtsan/lit.cfg.py +++ b/compiler-rt/test/rtsan/lit.cfg.py @@ -38,9 +38,7 @@ def build_invocation(compile_flags): ("%clangxx ", build_invocation(config.cxx_mode_flags + [config.target_cflags])) ) config.substitutions.append(("%clang_rtsan ", build_invocation(clang_rtsan_cflags))) -config.substitutions.append( - ("%clangxx_rtsan", build_invocation(clang_rtsan_cxxflags)) -) +config.substitutions.append(("%clangxx_rtsan", build_invocation(clang_rtsan_cxxflags))) config.substitutions.append(("%llvm_rtsan", llvm_rtsan)) config.substitutions.append( ( From 0f4a241ebd767fb71c56e0978ce459cc78f78275 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Wed, 3 Jul 2024 14:13:56 -0700 Subject: [PATCH 44/47] PR: Get rid of clang components only leave compiler-rt --- clang/include/clang/Basic/Features.def | 1 - clang/include/clang/Basic/Sanitizers.def | 3 -- clang/include/clang/Driver/SanitizerArgs.h | 1 - clang/lib/Driver/SanitizerArgs.cpp | 13 +++--- clang/lib/Driver/ToolChains/CommonArgs.cpp | 3 -- clang/lib/Driver/ToolChains/Darwin.cpp | 8 ---- clang/lib/Driver/ToolChains/Linux.cpp | 1 - clang/runtime/CMakeLists.txt | 1 - clang/test/Driver/fsanitize.c | 47 ---------------------- compiler-rt/lib/rtsan/tests/CMakeLists.txt | 18 ++++----- 10 files changed, 14 insertions(+), 82 deletions(-) diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 95064eeccf091..53f410d3cb4bd 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -103,7 +103,6 @@ FEATURE(memory_sanitizer, FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread)) FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow)) FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo)) -FEATURE(realtime_sanitizer, LangOpts.Sanitize.hasOneOf(SanitizerKind::Realtime)) FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics) FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls) FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns) diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def index 8a5df643ffa0c..bee35e9dca7c3 100644 --- a/clang/include/clang/Basic/Sanitizers.def +++ b/clang/include/clang/Basic/Sanitizers.def @@ -37,9 +37,6 @@ #endif -// RealtimeSanitizer -SANITIZER("realtime", Realtime) - // AddressSanitizer SANITIZER("address", Address) diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h index 6c0df926aec5b..47ef175302679 100644 --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -79,7 +79,6 @@ class SanitizerArgs { bool needsStableAbi() const { return StableABI; } bool needsMemProfRt() const { return NeedsMemProfRt; } - bool needsRtsanRt() const { return Sanitizers.has(SanitizerKind::Realtime); } bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); } bool needsHwasanRt() const { return Sanitizers.has(SanitizerKind::HWAddress); diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 543b7b315423e..86825a6ccf7a1 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -552,14 +552,11 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, SanitizerKind::Leak | SanitizerKind::Thread | SanitizerKind::Memory | SanitizerKind::KernelAddress | SanitizerKind::Scudo | SanitizerKind::SafeStack), - std::make_pair(SanitizerKind::MemTag, SanitizerKind::Address | - SanitizerKind::KernelAddress | - SanitizerKind::HWAddress | - SanitizerKind::KernelHWAddress), - std::make_pair(SanitizerKind::KCFI, SanitizerKind::Function), - std::make_pair(SanitizerKind::Realtime, - SanitizerKind::Address | SanitizerKind::Thread | - SanitizerKind::Undefined | SanitizerKind::Memory)}; + std::make_pair(SanitizerKind::MemTag, + SanitizerKind::Address | SanitizerKind::KernelAddress | + SanitizerKind::HWAddress | + SanitizerKind::KernelHWAddress), + std::make_pair(SanitizerKind::KCFI, SanitizerKind::Function)}; // Enable toolchain specific default sanitizers if not explicitly disabled. SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove; diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index c75e5a84b005d..c56a0c2c46c47 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1464,9 +1464,6 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, StaticRuntimes.push_back("asan_cxx"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsRtsanRt()) - StaticRuntimes.push_back("rtsan"); - if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt()) { StaticRuntimes.push_back("memprof"); if (SanArgs.linkCXXRuntimes()) diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 0c1c13edfdd45..64ab328a6d25f 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -1496,8 +1496,6 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, const char *sanitizer = nullptr; if (Sanitize.needsUbsanRt()) { sanitizer = "UndefinedBehaviorSanitizer"; - } else if (Sanitize.needsRtsanRt()) { - sanitizer = "RealtimeSanitizer"; } else if (Sanitize.needsAsanRt()) { sanitizer = "AddressSanitizer"; } else if (Sanitize.needsTsanRt()) { @@ -1520,11 +1518,6 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, AddLinkSanitizerLibArgs(Args, CmdArgs, "asan"); } } - if (Sanitize.needsRtsanRt()) { - assert(Sanitize.needsSharedRt() && - "Static sanitizer runtimes not supported"); - AddLinkSanitizerLibArgs(Args, CmdArgs, "rtsan"); - } if (Sanitize.needsLsanRt()) AddLinkSanitizerLibArgs(Args, CmdArgs, "lsan"); if (Sanitize.needsUbsanRt()) { @@ -3461,7 +3454,6 @@ SanitizerMask Darwin::getSupportedSanitizers() const { const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64; SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; - Res |= SanitizerKind::Realtime; Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Leak; diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 974224d97b67d..98a878e1d764d 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -795,7 +795,6 @@ SanitizerMask Linux::getSupportedSanitizers() const { const bool IsHexagon = getTriple().getArch() == llvm::Triple::hexagon; SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; - Res |= SanitizerKind::Realtime; Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Fuzzer; diff --git a/clang/runtime/CMakeLists.txt b/clang/runtime/CMakeLists.txt index 109de3d737548..65fcdc2868f03 100644 --- a/clang/runtime/CMakeLists.txt +++ b/clang/runtime/CMakeLists.txt @@ -150,7 +150,6 @@ if(LLVM_BUILD_EXTERNAL_COMPILER_RT AND EXISTS ${COMPILER_RT_SRC_ROOT}/) check-lsan check-msan check-profile - check-rtsan check-safestack check-sanitizer check-tsan diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c index d1a3ea9a37066..db14f6e195c64 100644 --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -1038,50 +1038,3 @@ // RUN: not %clang --target=aarch64-none-elf -fsanitize=dataflow %s -### 2>&1 | FileCheck %s -check-prefix=UNSUPPORTED-BAREMETAL // RUN: not %clang --target=arm-arm-none-eabi -fsanitize=shadow-call-stack %s -### 2>&1 | FileCheck %s -check-prefix=UNSUPPORTED-BAREMETAL // UNSUPPORTED-BAREMETAL: unsupported option '-fsanitize={{.*}}' for target - -// RUN: %clang --target=x86_64-apple-darwin -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-DARWIN -// CHECK-RTSAN-X86-64-DARWIN-NOT: unsupported option - -// RUN: %clang --target=x86_64-apple-darwin -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-DARWIN -// CHECK-RTSAN-X86-64-DARWIN-NOT: unsupported option -// RUN: %clang --target=x86_64-apple-macos -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-MACOS -// CHECK-RTSAN-X86-64-MACOS-NOT: unsupported option -// RUN: %clang --target=arm64-apple-macos -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-MACOS -// CHECK-RTSAN-ARM64-MACOS-NOT: unsupported option - -// RUN: %clang --target=arm64-apple-ios-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-IOSSIMULATOR -// CHECK-RTSAN-ARM64-IOSSIMULATOR-NOT: unsupported option - -// RUN: %clang --target=arm64-apple-watchos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-WATCHOSSIMULATOR -// CHECK-RTSAN-ARM64-WATCHOSSIMULATOR-NOT: unsupported option - -// RUN: %clang --target=arm64-apple-tvos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-TVOSSIMULATOR -// CHECK-RTSAN-ARM64-TVOSSIMULATOR-NOT: unsupported option - -// RUN: %clang --target=x86_64-apple-ios-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-IOSSIMULATOR -// CHECK-RTSAN-X86-64-IOSSIMULATOR-NOT: unsupported option - -// RUN: %clang --target=x86_64-apple-watchos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-WATCHOSSIMULATOR -// CHECK-RTSAN-X86-64-WATCHOSSIMULATOR-NOT: unsupported option - -// RUN: %clang --target=x86_64-apple-tvos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-TVOSSIMULATOR -// CHECK-RTSAN-X86-64-TVOSSIMULATOR-NOT: unsupported option - -// RUN: %clang --target=x86_64-linux-gnu -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-LINUX -// CHECK-RTSAN-X86-64-LINUX-NOT: unsupported option - -// RUN: not %clang --target=i386-pc-openbsd -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-OPENBSD -// CHECK-RTSAN-OPENBSD: unsupported option '-fsanitize=realtime' for target 'i386-pc-openbsd' - -// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-TSAN -// CHECK-REALTIME-TSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=thread' - -// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-ASAN -// CHECK-REALTIME-ASAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=address' - -// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-MSAN -// CHECK-REALTIME-MSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=memory' - -// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-UBSAN -// CHECK-REALTIME-UBSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=undefined' - diff --git a/compiler-rt/lib/rtsan/tests/CMakeLists.txt b/compiler-rt/lib/rtsan/tests/CMakeLists.txt index 87a5730685376..d96e538b255f4 100644 --- a/compiler-rt/lib/rtsan/tests/CMakeLists.txt +++ b/compiler-rt/lib/rtsan/tests/CMakeLists.txt @@ -54,15 +54,15 @@ endif() foreach(arch ${RTSAN_TEST_ARCH}) set(RtsanTestObjects) - generate_compiler_rt_tests(RtsanTestObjects - RtsanUnitTests "Rtsan-${arch}-Test" ${arch} - COMPILE_DEPS ${RTSAN_UNITTEST_HEADERS} - SOURCES ${RTSAN_INST_TEST_SOURCES} ${COMPILER_RT_GOOGLETEST_SOURCES} - DEPS llvm_gtest rtsan - CFLAGS ${RTSAN_UNITTEST_CFLAGS} -fsanitize=realtime - LINK_FLAGS ${RTSAN_UNITTEST_LINK_FLAGS} -fsanitize=realtime) - set_target_properties(RtsanUnitTests PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + + # TODO: Re-enable once -fsanitize=realtime exists in clang driver + #generate_compiler_rt_tests(RtsanTestObjects + # RtsanUnitTests "Rtsan-${arch}-Test" ${arch} + # COMPILE_DEPS ${RTSAN_UNITTEST_HEADERS} + # SOURCES ${RTSAN_INST_TEST_SOURCES} ${COMPILER_RT_GOOGLETEST_SOURCES} + # DEPS llvm_gtest rtsan + # CFLAGS ${RTSAN_UNITTEST_CFLAGS} -fsanitize=realtime + # LINK_FLAGS ${RTSAN_UNITTEST_LINK_FLAGS} -fsanitize=realtime) set(RTSAN_TEST_RUNTIME RTRtsanTest.${arch}) if(APPLE) From 428e17e775e902c8ff575e12092b8e52fa24f34a Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:34:55 -0700 Subject: [PATCH 45/47] PR: MaskRay comments - remove empty initializers - better namespace compliance with LLVM standards - Fix lit.cfg.py to remove crufty elements not needed - Change name of InternalFree, add explainer comment --- compiler-rt/lib/rtsan/rtsan_context.cpp | 33 +++--- compiler-rt/lib/rtsan/rtsan_interceptors.cpp | 105 ++++++++---------- compiler-rt/lib/rtsan/rtsan_stack.cpp | 2 +- .../lib/rtsan/tests/rtsan_test_functional.cpp | 20 ++-- compiler-rt/test/rtsan/lit.cfg.py | 18 --- 5 files changed, 77 insertions(+), 101 deletions(-) diff --git a/compiler-rt/lib/rtsan/rtsan_context.cpp b/compiler-rt/lib/rtsan/rtsan_context.cpp index 9eba3fb0ec25a..f761ddedce672 100644 --- a/compiler-rt/lib/rtsan/rtsan_context.cpp +++ b/compiler-rt/lib/rtsan/rtsan_context.cpp @@ -23,11 +23,13 @@ static pthread_key_t context_key; static pthread_once_t key_once = PTHREAD_ONCE_INIT; -static void internalFree(void *ptr) { __sanitizer::InternalFree(ptr); } +// InternalFree cannot be passed directly to pthread_key_create +// because it expects a signature with only one arg +static void InternalFreeWrapper(void *ptr) { __sanitizer::InternalFree(ptr); } static __rtsan::Context &GetContextForThisThreadImpl() { auto make_thread_local_context_key = []() { - CHECK_EQ(pthread_key_create(&context_key, internalFree), 0); + CHECK_EQ(pthread_key_create(&context_key, InternalFreeWrapper), 0); }; pthread_once(&key_once, make_thread_local_context_key); @@ -59,19 +61,18 @@ static __rtsan::Context &GetContextForThisThreadImpl() { */ static void InvokeViolationDetectedAction() { exit(EXIT_FAILURE); } -namespace __rtsan { +__rtsan::Context::Context() = default; -Context::Context() = default; +void __rtsan::Context::RealtimePush() { realtime_depth++; } -void Context::RealtimePush() { realtime_depth++; } +void __rtsan::Context::RealtimePop() { realtime_depth--; } -void Context::RealtimePop() { realtime_depth--; } +void __rtsan::Context::BypassPush() { bypass_depth++; } -void Context::BypassPush() { bypass_depth++; } +void __rtsan::Context::BypassPop() { bypass_depth--; } -void Context::BypassPop() { bypass_depth--; } - -void Context::ExpectNotRealtime(const char *intercepted_function_name) { +void __rtsan::Context::ExpectNotRealtime( + const char *intercepted_function_name) { if (InRealtimeContext() && !IsBypassed()) { BypassPush(); PrintDiagnostics(intercepted_function_name); @@ -80,11 +81,11 @@ void Context::ExpectNotRealtime(const char *intercepted_function_name) { } } -bool Context::InRealtimeContext() const { return realtime_depth > 0; } +bool __rtsan::Context::InRealtimeContext() const { return realtime_depth > 0; } -bool Context::IsBypassed() const { return bypass_depth > 0; } +bool __rtsan::Context::IsBypassed() const { return bypass_depth > 0; } -void Context::PrintDiagnostics(const char *intercepted_function_name) { +void __rtsan::Context::PrintDiagnostics(const char *intercepted_function_name) { fprintf(stderr, "Real-time violation: intercepted call to real-time unsafe function " "`%s` in real-time context! Stack trace:\n", @@ -92,6 +93,6 @@ void Context::PrintDiagnostics(const char *intercepted_function_name) { __rtsan::PrintStackTrace(); } -Context &GetContextForThisThread() { return GetContextForThisThreadImpl(); } - -} // namespace __rtsan +__rtsan::Context &__rtsan::GetContextForThisThread() { + return GetContextForThisThreadImpl(); +} diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp index adcad6c5de412..3a65f9d3f779d 100644 --- a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp @@ -16,10 +16,6 @@ #include "interception/interception.h" #include "rtsan/rtsan_context.h" -#if !SANITIZER_LINUX && !SANITIZER_APPLE -#error Sorry, rtsan does not yet support this platform -#endif - #if SANITIZER_APPLE #include #include @@ -39,18 +35,17 @@ using namespace __sanitizer; -namespace __rtsan { void ExpectNotRealtime(const char *intercepted_function_name) { - GetContextForThisThread().ExpectNotRealtime(intercepted_function_name); + __rtsan::GetContextForThisThread().ExpectNotRealtime( + intercepted_function_name); } -} // namespace __rtsan // Filesystem INTERCEPTOR(int, open, const char *path, int oflag, ...) { // TODO Establish whether we should intercept here if the flag contains // O_NONBLOCK - __rtsan::ExpectNotRealtime("open"); + ExpectNotRealtime("open"); va_list args; va_start(args, oflag); @@ -64,7 +59,7 @@ INTERCEPTOR(int, open, const char *path, int oflag, ...) { INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) { // TODO Establish whether we should intercept here if the flag contains // O_NONBLOCK - __rtsan::ExpectNotRealtime("openat"); + ExpectNotRealtime("openat"); va_list args; va_start(args, oflag); @@ -78,13 +73,13 @@ INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) { INTERCEPTOR(int, creat, const char *path, mode_t mode) { // TODO Establish whether we should intercept here if the flag contains // O_NONBLOCK - __rtsan::ExpectNotRealtime("creat"); + ExpectNotRealtime("creat"); const int result = REAL(creat)(path, mode); return result; } INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) { - __rtsan::ExpectNotRealtime("fcntl"); + ExpectNotRealtime("fcntl"); va_list args; va_start(args, cmd); @@ -105,40 +100,40 @@ INTERCEPTOR(int, fcntl, int filedes, int cmd, ...) { } INTERCEPTOR(int, close, int filedes) { - __rtsan::ExpectNotRealtime("close"); + ExpectNotRealtime("close"); return REAL(close)(filedes); } INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) { - __rtsan::ExpectNotRealtime("fopen"); + ExpectNotRealtime("fopen"); return REAL(fopen)(path, mode); } INTERCEPTOR(size_t, fread, void *ptr, size_t size, size_t nitems, FILE *stream) { - __rtsan::ExpectNotRealtime("fread"); + ExpectNotRealtime("fread"); return REAL(fread)(ptr, size, nitems, stream); } INTERCEPTOR(size_t, fwrite, const void *ptr, size_t size, size_t nitems, FILE *stream) { - __rtsan::ExpectNotRealtime("fwrite"); + ExpectNotRealtime("fwrite"); return REAL(fwrite)(ptr, size, nitems, stream); } INTERCEPTOR(int, fclose, FILE *stream) { - __rtsan::ExpectNotRealtime("fclose"); + ExpectNotRealtime("fclose"); return REAL(fclose)(stream); } INTERCEPTOR(int, fputs, const char *s, FILE *stream) { - __rtsan::ExpectNotRealtime("fputs"); + ExpectNotRealtime("fputs"); return REAL(fputs)(s, stream); } // Streams INTERCEPTOR(int, puts, const char *s) { - __rtsan::ExpectNotRealtime("puts"); + ExpectNotRealtime("puts"); return REAL(puts)(s); } @@ -148,135 +143,135 @@ INTERCEPTOR(int, puts, const char *s) { // OSSpinLockLock is deprecated, but still in use in libc++ #pragma clang diagnostic ignored "-Wdeprecated-declarations" INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) { - __rtsan::ExpectNotRealtime("OSSpinLockLock"); + ExpectNotRealtime("OSSpinLockLock"); return REAL(OSSpinLockLock)(lock); } #pragma clang diagnostic pop INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) { - __rtsan::ExpectNotRealtime("os_unfair_lock_lock"); + ExpectNotRealtime("os_unfair_lock_lock"); return REAL(os_unfair_lock_lock)(lock); } #elif SANITIZER_LINUX INTERCEPTOR(int, pthread_spin_lock, pthread_spinlock_t *spinlock) { - __rtsan::ExpectNotRealtime("pthread_spin_lock"); + ExpectNotRealtime("pthread_spin_lock"); return REAL(pthread_spin_lock)(spinlock); } #endif INTERCEPTOR(int, pthread_create, pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { - __rtsan::ExpectNotRealtime("pthread_create"); + ExpectNotRealtime("pthread_create"); return REAL(pthread_create)(thread, attr, start_routine, arg); } INTERCEPTOR(int, pthread_mutex_lock, pthread_mutex_t *mutex) { - __rtsan::ExpectNotRealtime("pthread_mutex_lock"); + ExpectNotRealtime("pthread_mutex_lock"); return REAL(pthread_mutex_lock)(mutex); } INTERCEPTOR(int, pthread_mutex_unlock, pthread_mutex_t *mutex) { - __rtsan::ExpectNotRealtime("pthread_mutex_unlock"); + ExpectNotRealtime("pthread_mutex_unlock"); return REAL(pthread_mutex_unlock)(mutex); } INTERCEPTOR(int, pthread_join, pthread_t thread, void **value_ptr) { - __rtsan::ExpectNotRealtime("pthread_join"); + ExpectNotRealtime("pthread_join"); return REAL(pthread_join)(thread, value_ptr); } INTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *cond) { - __rtsan::ExpectNotRealtime("pthread_cond_signal"); + ExpectNotRealtime("pthread_cond_signal"); return REAL(pthread_cond_signal)(cond); } INTERCEPTOR(int, pthread_cond_broadcast, pthread_cond_t *cond) { - __rtsan::ExpectNotRealtime("pthread_cond_broadcast"); + ExpectNotRealtime("pthread_cond_broadcast"); return REAL(pthread_cond_broadcast)(cond); } INTERCEPTOR(int, pthread_cond_wait, pthread_cond_t *cond, pthread_mutex_t *mutex) { - __rtsan::ExpectNotRealtime("pthread_cond_wait"); + ExpectNotRealtime("pthread_cond_wait"); return REAL(pthread_cond_wait)(cond, mutex); } INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *cond, pthread_mutex_t *mutex, const timespec *ts) { - __rtsan::ExpectNotRealtime("pthread_cond_timedwait"); + ExpectNotRealtime("pthread_cond_timedwait"); return REAL(pthread_cond_timedwait)(cond, mutex, ts); } INTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *lock) { - __rtsan::ExpectNotRealtime("pthread_rwlock_rdlock"); + ExpectNotRealtime("pthread_rwlock_rdlock"); return REAL(pthread_rwlock_rdlock)(lock); } INTERCEPTOR(int, pthread_rwlock_unlock, pthread_rwlock_t *lock) { - __rtsan::ExpectNotRealtime("pthread_rwlock_unlock"); + ExpectNotRealtime("pthread_rwlock_unlock"); return REAL(pthread_rwlock_unlock)(lock); } INTERCEPTOR(int, pthread_rwlock_wrlock, pthread_rwlock_t *lock) { - __rtsan::ExpectNotRealtime("pthread_rwlock_wrlock"); + ExpectNotRealtime("pthread_rwlock_wrlock"); return REAL(pthread_rwlock_wrlock)(lock); } // Sleeping INTERCEPTOR(unsigned int, sleep, unsigned int s) { - __rtsan::ExpectNotRealtime("sleep"); + ExpectNotRealtime("sleep"); return REAL(sleep)(s); } INTERCEPTOR(int, usleep, useconds_t u) { - __rtsan::ExpectNotRealtime("usleep"); + ExpectNotRealtime("usleep"); return REAL(usleep)(u); } INTERCEPTOR(int, nanosleep, const struct timespec *rqtp, struct timespec *rmtp) { - __rtsan::ExpectNotRealtime("nanosleep"); + ExpectNotRealtime("nanosleep"); return REAL(nanosleep)(rqtp, rmtp); } // Memory INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) { - __rtsan::ExpectNotRealtime("calloc"); + ExpectNotRealtime("calloc"); return REAL(calloc)(num, size); } INTERCEPTOR(void, free, void *ptr) { if (ptr != NULL) { - __rtsan::ExpectNotRealtime("free"); + ExpectNotRealtime("free"); } return REAL(free)(ptr); } INTERCEPTOR(void *, malloc, SIZE_T size) { - __rtsan::ExpectNotRealtime("malloc"); + ExpectNotRealtime("malloc"); return REAL(malloc)(size); } INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) { - __rtsan::ExpectNotRealtime("realloc"); + ExpectNotRealtime("realloc"); return REAL(realloc)(ptr, size); } INTERCEPTOR(void *, reallocf, void *ptr, SIZE_T size) { - __rtsan::ExpectNotRealtime("reallocf"); + ExpectNotRealtime("reallocf"); return REAL(reallocf)(ptr, size); } INTERCEPTOR(void *, valloc, SIZE_T size) { - __rtsan::ExpectNotRealtime("valloc"); + ExpectNotRealtime("valloc"); return REAL(valloc)(size); } #if SANITIZER_INTERCEPT_ALIGNED_ALLOC INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) { - __rtsan::ExpectNotRealtime("aligned_alloc"); + ExpectNotRealtime("aligned_alloc"); return REAL(aligned_alloc)(alignment, size); } #define RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc) @@ -285,71 +280,70 @@ INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) { #endif INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) { - __rtsan::ExpectNotRealtime("posix_memalign"); + ExpectNotRealtime("posix_memalign"); return REAL(posix_memalign)(memptr, alignment, size); } #if SANITIZER_INTERCEPT_MEMALIGN INTERCEPTOR(void *, memalign, size_t alignment, size_t size) { - __rtsan::ExpectNotRealtime("memalign"); + ExpectNotRealtime("memalign"); return REAL(memalign)(alignment, size); } #endif #if SANITIZER_INTERCEPT_PVALLOC INTERCEPTOR(void *, pvalloc, size_t size) { - __rtsan::ExpectNotRealtime("pvalloc"); + ExpectNotRealtime("pvalloc"); return REAL(pvalloc)(size); } #endif // Sockets INTERCEPTOR(int, socket, int domain, int type, int protocol) { - __rtsan::ExpectNotRealtime("socket"); + ExpectNotRealtime("socket"); return REAL(socket)(domain, type, protocol); } INTERCEPTOR(ssize_t, send, int sockfd, const void *buf, size_t len, int flags) { - __rtsan::ExpectNotRealtime("send"); + ExpectNotRealtime("send"); return REAL(send)(sockfd, buf, len, flags); } INTERCEPTOR(ssize_t, sendmsg, int socket, const struct msghdr *message, int flags) { - __rtsan::ExpectNotRealtime("sendmsg"); + ExpectNotRealtime("sendmsg"); return REAL(sendmsg)(socket, message, flags); } INTERCEPTOR(ssize_t, sendto, int socket, const void *buffer, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len) { - __rtsan::ExpectNotRealtime("sendto"); + ExpectNotRealtime("sendto"); return REAL(sendto)(socket, buffer, length, flags, dest_addr, dest_len); } INTERCEPTOR(ssize_t, recv, int socket, void *buffer, size_t length, int flags) { - __rtsan::ExpectNotRealtime("recv"); + ExpectNotRealtime("recv"); return REAL(recv)(socket, buffer, length, flags); } INTERCEPTOR(ssize_t, recvfrom, int socket, void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len) { - __rtsan::ExpectNotRealtime("recvfrom"); + ExpectNotRealtime("recvfrom"); return REAL(recvfrom)(socket, buffer, length, flags, address, address_len); } INTERCEPTOR(ssize_t, recvmsg, int socket, struct msghdr *message, int flags) { - __rtsan::ExpectNotRealtime("recvmsg"); + ExpectNotRealtime("recvmsg"); return REAL(recvmsg)(socket, message, flags); } INTERCEPTOR(int, shutdown, int socket, int how) { - __rtsan::ExpectNotRealtime("shutdown"); + ExpectNotRealtime("shutdown"); return REAL(shutdown)(socket, how); } // Preinit -namespace __rtsan { -void InitializeInterceptors() { +void __rtsan::InitializeInterceptors() { INTERCEPT_FUNCTION(calloc); INTERCEPT_FUNCTION(free); INTERCEPT_FUNCTION(malloc); @@ -409,4 +403,3 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(recvfrom); INTERCEPT_FUNCTION(shutdown); } -} // namespace __rtsan diff --git a/compiler-rt/lib/rtsan/rtsan_stack.cpp b/compiler-rt/lib/rtsan/rtsan_stack.cpp index ff0af8fe675f3..43fd5fbf05509 100644 --- a/compiler-rt/lib/rtsan/rtsan_stack.cpp +++ b/compiler-rt/lib/rtsan/rtsan_stack.cpp @@ -14,6 +14,7 @@ #include using namespace __sanitizer; +using namespace __rtsan; // We must define our own implementation of this method for our runtime. // This one is just copied from UBSan. @@ -37,7 +38,6 @@ static void SetGlobalStackTraceFormat() { OverrideCommonFlags(cf); } -using namespace __rtsan; void __rtsan::PrintStackTrace() { BufferedStackTrace stack{}; diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_functional.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_functional.cpp index 2f3cd3a8bd287..97afb1eefb640 100644 --- a/compiler-rt/lib/rtsan/tests/rtsan_test_functional.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_functional.cpp @@ -41,7 +41,7 @@ using namespace rtsan_testing; using namespace std::chrono_literals; TEST(TestRtsan, VectorPushBackAllocationDiesWhenRealtime) { - std::vector vec{}; + std::vector vec; auto Func = [&vec]() { vec.push_back(0.4f); }; ExpectRealtimeDeath(Func); ASSERT_EQ(0u, vec.size()); @@ -79,14 +79,14 @@ TEST(TestRtsan, OfstreamCreationDiesWhenRealtime) { } TEST(TestRtsan, LockingAMutexDiesWhenRealtime) { - std::mutex mutex{}; + std::mutex mutex; auto Func = [&]() { mutex.lock(); }; ExpectRealtimeDeath(Func); ExpectNonRealtimeSurvival(Func); } TEST(TestRtsan, UnlockingAMutexDiesWhenRealtime) { - std::mutex mutex{}; + std::mutex mutex; mutex.lock(); auto Func = [&]() { mutex.unlock(); }; ExpectRealtimeDeath(Func); @@ -96,14 +96,14 @@ TEST(TestRtsan, UnlockingAMutexDiesWhenRealtime) { #if RTSAN_TEST_SHARED_MUTEX TEST(TestRtsan, LockingASharedMutexDiesWhenRealtime) { - std::shared_mutex mutex{}; + std::shared_mutex mutex; auto Func = [&]() { mutex.lock(); }; ExpectRealtimeDeath(Func); ExpectNonRealtimeSurvival(Func); } TEST(TestRtsan, UnlockingASharedMutexDiesWhenRealtime) { - std::shared_mutex mutex{}; + std::shared_mutex mutex; mutex.lock(); auto Func = [&]() { mutex.unlock(); }; ExpectRealtimeDeath(Func); @@ -111,14 +111,14 @@ TEST(TestRtsan, UnlockingASharedMutexDiesWhenRealtime) { } TEST(TestRtsan, SharedLockingASharedMutexDiesWhenRealtime) { - std::shared_mutex mutex{}; + std::shared_mutex mutex; auto Func = [&]() { mutex.lock_shared(); }; ExpectRealtimeDeath(Func); ExpectNonRealtimeSurvival(Func); } TEST(TestRtsan, SharedUnlockingASharedMutexDiesWhenRealtime) { - std::shared_mutex mutex{}; + std::shared_mutex mutex; mutex.lock_shared(); auto Func = [&]() { mutex.unlock_shared(); }; ExpectRealtimeDeath(Func); @@ -141,7 +141,7 @@ void InvokeStdFunction(std::function &&function) { function(); } } // namespace TEST(TestRtsan, CopyingALambdaWithLargeCaptureDiesWhenRealtime) { - std::array lots_of_data{}; + std::array lots_of_data; auto lambda = [lots_of_data]() mutable { // Stop everything getting optimised out lots_of_data[3] = 0.25f; @@ -158,7 +158,7 @@ TEST(TestRtsan, AccessingALargeAtomicVariableDiesWhenRealtime) { ASSERT_TRUE(small_atomic.is_lock_free()); RealtimeInvoke([&small_atomic]() { float x = small_atomic.load(); }); - std::atomic> large_atomic{}; + std::atomic> large_atomic; ASSERT_FALSE(large_atomic.is_lock_free()); auto Func = [&]() { auto x = large_atomic.load(); }; ExpectRealtimeDeath(Func); @@ -196,7 +196,7 @@ TEST(TestRtsan, ThrowingAnExceptionDiesWhenRealtime) { } TEST(TestRtsan, DoesNotDieIfTurnedOff) { - std::mutex mutex{}; + std::mutex mutex; auto RealtimeUnsafeFunc = [&]() { __rtsan_off(); mutex.lock(); diff --git a/compiler-rt/test/rtsan/lit.cfg.py b/compiler-rt/test/rtsan/lit.cfg.py index 7ecefa11aca29..b262ecfa7fb4b 100644 --- a/compiler-rt/test/rtsan/lit.cfg.py +++ b/compiler-rt/test/rtsan/lit.cfg.py @@ -9,14 +9,6 @@ # Setup default compiler flags use with -frtsan-instrument option. clang_rtsan_cflags = ["-frtsan-instrument", config.target_cflags] -# If libc++ was used to build rtsan libraries, libc++ is needed. Fix applied -# to Linux only since -rpath may not be portable. This can be extended to -# other platforms. -if config.libcxx_used == "1" and config.host_os == "Linux": - clang_rtsan_cflags = clang_rtsan_cflags + ( - ["-L%s -lc++ -Wl,-rpath=%s" % (config.llvm_shlib_dir, config.llvm_shlib_dir)] - ) - clang_rtsan_cxxflags = config.cxx_mode_flags + clang_rtsan_cflags @@ -40,16 +32,6 @@ def build_invocation(compile_flags): config.substitutions.append(("%clang_rtsan ", build_invocation(clang_rtsan_cflags))) config.substitutions.append(("%clangxx_rtsan", build_invocation(clang_rtsan_cxxflags))) config.substitutions.append(("%llvm_rtsan", llvm_rtsan)) -config.substitutions.append( - ( - "%rtsanlib", - ( - "-lm -lpthread %s -lrt -L%s " - "-Wl,-whole-archive -lclang_rt.rtsan%s -Wl,-no-whole-archive" - ) - % (libdl_flag, config.compiler_rt_libdir, config.target_suffix), - ) -) # Default test suffixes. config.suffixes = [".c", ".cpp"] From ef8bc6bd630d75d2e4e9e1e26c8634b7a68a3d74 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:20:59 -0700 Subject: [PATCH 46/47] A few pieces of cruft from the rebase/merge --- compiler-rt/cmake/config-ix.cmake | 2 +- compiler-rt/lib/rtsan/tests/rtsan_test_utilities.h | 4 ++-- libcxx/include/CMakeLists.txt | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index 3ee820f794717..1130f9f721df4 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -462,7 +462,7 @@ if(APPLE) set(MIN_OSX_VERSION ${DEFAULT_SANITIZER_MIN_OSX_VERSION}) endif() -# Note: In order to target x86_64h on OS X the minimum deployment target must + # Note: In order to target x86_64h on OS X the minimum deployment target must # be 10.8 or higher. if(MIN_OSX_VERSION VERSION_LESS "10.7") message(FATAL_ERROR "macOS deployment target '${SANITIZER_MIN_OSX_VERSION}' is too old.") diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_utilities.h b/compiler-rt/lib/rtsan/tests/rtsan_test_utilities.h index d24182ff7ef59..6ca09cf657094 100644 --- a/compiler-rt/lib/rtsan/tests/rtsan_test_utilities.h +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_utilities.h @@ -23,7 +23,7 @@ template void RealtimeInvoke(Function &&Func) { } template -void expectRealtimeDeath(Function &&Func, +void ExpectRealtimeDeath(Function &&Func, const char *intercepted_method_name = nullptr) { using namespace testing; @@ -40,7 +40,7 @@ void expectRealtimeDeath(Function &&Func, ExitedWithCode(EXIT_FAILURE), GetExpectedErrorSubstring()); } -template void expectNonrealtimeSurvival(Function &&Func) { +template void ExpectNonRealtimeSurvival(Function &&Func) { std::forward(Func)(); } diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 2c8910dc26678..8d0ffd6ed725b 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -1041,6 +1041,7 @@ add_custom_command(OUTPUT "${LIBCXX_GENERATED_INCLUDE_DIR}/libcxx.imp" list(APPEND _all_includes "${LIBCXX_GENERATED_INCLUDE_DIR}/libcxx.imp") add_custom_target(generate-cxx-headers ALL DEPENDS ${_all_includes}) + add_library(cxx-headers INTERFACE) target_link_libraries(cxx-headers INTERFACE libcxx-abi-headers) add_dependencies(cxx-headers generate-cxx-headers) From 403acd02a3962f3f3450aaf7153ba56b14e9c1d4 Mon Sep 17 00:00:00 2001 From: Chris Apple <14171107+cjappl@users.noreply.github.com> Date: Mon, 8 Jul 2024 21:33:32 -0700 Subject: [PATCH 47/47] Revert "PR: Get rid of clang components only leave compiler-rt" This reverts commit eb7542cb2c93f1e51fb9069f4629bb2990e30eff. --- clang/include/clang/Basic/Features.def | 1 + clang/include/clang/Basic/Sanitizers.def | 3 ++ clang/include/clang/Driver/SanitizerArgs.h | 1 + clang/lib/Driver/SanitizerArgs.cpp | 13 +++--- clang/lib/Driver/ToolChains/CommonArgs.cpp | 3 ++ clang/lib/Driver/ToolChains/Darwin.cpp | 8 ++++ clang/lib/Driver/ToolChains/Linux.cpp | 1 + clang/runtime/CMakeLists.txt | 1 + clang/test/Driver/fsanitize.c | 47 ++++++++++++++++++++++ compiler-rt/lib/rtsan/tests/CMakeLists.txt | 18 ++++----- 10 files changed, 82 insertions(+), 14 deletions(-) diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 53f410d3cb4bd..95064eeccf091 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -103,6 +103,7 @@ FEATURE(memory_sanitizer, FEATURE(thread_sanitizer, LangOpts.Sanitize.has(SanitizerKind::Thread)) FEATURE(dataflow_sanitizer, LangOpts.Sanitize.has(SanitizerKind::DataFlow)) FEATURE(scudo, LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo)) +FEATURE(realtime_sanitizer, LangOpts.Sanitize.hasOneOf(SanitizerKind::Realtime)) FEATURE(ptrauth_intrinsics, LangOpts.PointerAuthIntrinsics) FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls) FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns) diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def index bee35e9dca7c3..8a5df643ffa0c 100644 --- a/clang/include/clang/Basic/Sanitizers.def +++ b/clang/include/clang/Basic/Sanitizers.def @@ -37,6 +37,9 @@ #endif +// RealtimeSanitizer +SANITIZER("realtime", Realtime) + // AddressSanitizer SANITIZER("address", Address) diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h index 47ef175302679..6c0df926aec5b 100644 --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -79,6 +79,7 @@ class SanitizerArgs { bool needsStableAbi() const { return StableABI; } bool needsMemProfRt() const { return NeedsMemProfRt; } + bool needsRtsanRt() const { return Sanitizers.has(SanitizerKind::Realtime); } bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); } bool needsHwasanRt() const { return Sanitizers.has(SanitizerKind::HWAddress); diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 86825a6ccf7a1..543b7b315423e 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -552,11 +552,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, SanitizerKind::Leak | SanitizerKind::Thread | SanitizerKind::Memory | SanitizerKind::KernelAddress | SanitizerKind::Scudo | SanitizerKind::SafeStack), - std::make_pair(SanitizerKind::MemTag, - SanitizerKind::Address | SanitizerKind::KernelAddress | - SanitizerKind::HWAddress | - SanitizerKind::KernelHWAddress), - std::make_pair(SanitizerKind::KCFI, SanitizerKind::Function)}; + std::make_pair(SanitizerKind::MemTag, SanitizerKind::Address | + SanitizerKind::KernelAddress | + SanitizerKind::HWAddress | + SanitizerKind::KernelHWAddress), + std::make_pair(SanitizerKind::KCFI, SanitizerKind::Function), + std::make_pair(SanitizerKind::Realtime, + SanitizerKind::Address | SanitizerKind::Thread | + SanitizerKind::Undefined | SanitizerKind::Memory)}; // Enable toolchain specific default sanitizers if not explicitly disabled. SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove; diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index c56a0c2c46c47..c75e5a84b005d 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1464,6 +1464,9 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, StaticRuntimes.push_back("asan_cxx"); } + if (!SanArgs.needsSharedRt() && SanArgs.needsRtsanRt()) + StaticRuntimes.push_back("rtsan"); + if (!SanArgs.needsSharedRt() && SanArgs.needsMemProfRt()) { StaticRuntimes.push_back("memprof"); if (SanArgs.linkCXXRuntimes()) diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 64ab328a6d25f..0c1c13edfdd45 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -1496,6 +1496,8 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, const char *sanitizer = nullptr; if (Sanitize.needsUbsanRt()) { sanitizer = "UndefinedBehaviorSanitizer"; + } else if (Sanitize.needsRtsanRt()) { + sanitizer = "RealtimeSanitizer"; } else if (Sanitize.needsAsanRt()) { sanitizer = "AddressSanitizer"; } else if (Sanitize.needsTsanRt()) { @@ -1518,6 +1520,11 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, AddLinkSanitizerLibArgs(Args, CmdArgs, "asan"); } } + if (Sanitize.needsRtsanRt()) { + assert(Sanitize.needsSharedRt() && + "Static sanitizer runtimes not supported"); + AddLinkSanitizerLibArgs(Args, CmdArgs, "rtsan"); + } if (Sanitize.needsLsanRt()) AddLinkSanitizerLibArgs(Args, CmdArgs, "lsan"); if (Sanitize.needsUbsanRt()) { @@ -3454,6 +3461,7 @@ SanitizerMask Darwin::getSupportedSanitizers() const { const bool IsAArch64 = getTriple().getArch() == llvm::Triple::aarch64; SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::Realtime; Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Leak; diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 98a878e1d764d..974224d97b67d 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -795,6 +795,7 @@ SanitizerMask Linux::getSupportedSanitizers() const { const bool IsHexagon = getTriple().getArch() == llvm::Triple::hexagon; SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::Realtime; Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Fuzzer; diff --git a/clang/runtime/CMakeLists.txt b/clang/runtime/CMakeLists.txt index 65fcdc2868f03..109de3d737548 100644 --- a/clang/runtime/CMakeLists.txt +++ b/clang/runtime/CMakeLists.txt @@ -150,6 +150,7 @@ if(LLVM_BUILD_EXTERNAL_COMPILER_RT AND EXISTS ${COMPILER_RT_SRC_ROOT}/) check-lsan check-msan check-profile + check-rtsan check-safestack check-sanitizer check-tsan diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c index db14f6e195c64..d1a3ea9a37066 100644 --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -1038,3 +1038,50 @@ // RUN: not %clang --target=aarch64-none-elf -fsanitize=dataflow %s -### 2>&1 | FileCheck %s -check-prefix=UNSUPPORTED-BAREMETAL // RUN: not %clang --target=arm-arm-none-eabi -fsanitize=shadow-call-stack %s -### 2>&1 | FileCheck %s -check-prefix=UNSUPPORTED-BAREMETAL // UNSUPPORTED-BAREMETAL: unsupported option '-fsanitize={{.*}}' for target + +// RUN: %clang --target=x86_64-apple-darwin -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-DARWIN +// CHECK-RTSAN-X86-64-DARWIN-NOT: unsupported option + +// RUN: %clang --target=x86_64-apple-darwin -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-DARWIN +// CHECK-RTSAN-X86-64-DARWIN-NOT: unsupported option +// RUN: %clang --target=x86_64-apple-macos -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-MACOS +// CHECK-RTSAN-X86-64-MACOS-NOT: unsupported option +// RUN: %clang --target=arm64-apple-macos -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-MACOS +// CHECK-RTSAN-ARM64-MACOS-NOT: unsupported option + +// RUN: %clang --target=arm64-apple-ios-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-IOSSIMULATOR +// CHECK-RTSAN-ARM64-IOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=arm64-apple-watchos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-WATCHOSSIMULATOR +// CHECK-RTSAN-ARM64-WATCHOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=arm64-apple-tvos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-ARM64-TVOSSIMULATOR +// CHECK-RTSAN-ARM64-TVOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=x86_64-apple-ios-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-IOSSIMULATOR +// CHECK-RTSAN-X86-64-IOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=x86_64-apple-watchos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-WATCHOSSIMULATOR +// CHECK-RTSAN-X86-64-WATCHOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=x86_64-apple-tvos-simulator -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-TVOSSIMULATOR +// CHECK-RTSAN-X86-64-TVOSSIMULATOR-NOT: unsupported option + +// RUN: %clang --target=x86_64-linux-gnu -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-X86-64-LINUX +// CHECK-RTSAN-X86-64-LINUX-NOT: unsupported option + +// RUN: not %clang --target=i386-pc-openbsd -fsanitize=realtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RTSAN-OPENBSD +// CHECK-RTSAN-OPENBSD: unsupported option '-fsanitize=realtime' for target 'i386-pc-openbsd' + +// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-TSAN +// CHECK-REALTIME-TSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=thread' + +// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-ASAN +// CHECK-REALTIME-ASAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=address' + +// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-MSAN +// CHECK-REALTIME-MSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=memory' + +// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=realtime,undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-REALTIME-UBSAN +// CHECK-REALTIME-UBSAN: error: invalid argument '-fsanitize=realtime' not allowed with '-fsanitize=undefined' + diff --git a/compiler-rt/lib/rtsan/tests/CMakeLists.txt b/compiler-rt/lib/rtsan/tests/CMakeLists.txt index d96e538b255f4..87a5730685376 100644 --- a/compiler-rt/lib/rtsan/tests/CMakeLists.txt +++ b/compiler-rt/lib/rtsan/tests/CMakeLists.txt @@ -54,15 +54,15 @@ endif() foreach(arch ${RTSAN_TEST_ARCH}) set(RtsanTestObjects) - - # TODO: Re-enable once -fsanitize=realtime exists in clang driver - #generate_compiler_rt_tests(RtsanTestObjects - # RtsanUnitTests "Rtsan-${arch}-Test" ${arch} - # COMPILE_DEPS ${RTSAN_UNITTEST_HEADERS} - # SOURCES ${RTSAN_INST_TEST_SOURCES} ${COMPILER_RT_GOOGLETEST_SOURCES} - # DEPS llvm_gtest rtsan - # CFLAGS ${RTSAN_UNITTEST_CFLAGS} -fsanitize=realtime - # LINK_FLAGS ${RTSAN_UNITTEST_LINK_FLAGS} -fsanitize=realtime) + generate_compiler_rt_tests(RtsanTestObjects + RtsanUnitTests "Rtsan-${arch}-Test" ${arch} + COMPILE_DEPS ${RTSAN_UNITTEST_HEADERS} + SOURCES ${RTSAN_INST_TEST_SOURCES} ${COMPILER_RT_GOOGLETEST_SOURCES} + DEPS llvm_gtest rtsan + CFLAGS ${RTSAN_UNITTEST_CFLAGS} -fsanitize=realtime + LINK_FLAGS ${RTSAN_UNITTEST_LINK_FLAGS} -fsanitize=realtime) + set_target_properties(RtsanUnitTests PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set(RTSAN_TEST_RUNTIME RTRtsanTest.${arch}) if(APPLE)