-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[compiler-rt] Realtime Sanitizer: Introduce Realtime Sanitizer (RTSan) backend #92460
Merged
Merged
Changes from 46 commits
Commits
Show all changes
47 commits
Select commit
Hold shift + click to select a range
81ec957
First try
cjappl 76d9cd9
Fixing some clang tidy foo
cjappl 7b476ec
One round of renaming
cjappl cfbde34
Another round of style cleanups
cjappl 3dd143f
more auto removal, more case fixing
cjappl 9eaded1
Missing end of namespace comment
cjappl 11030b6
Fix one naming issue
cjappl d92cb45
No more unistd
cjappl 985fe27
Radsan context moved to impl
cjappl 9d4e76f
Promise lit tests later
cjappl 04f234a
Move radsan_test and add helper comment to top of file
cjappl 41f1cd1
Only link radsan statically
cjappl 680189c
Fix comments in radsan.h
cjappl b1d0789
Replace inlined exit with selected action stub
davidtrevelyan b5a7f7a
Codeowners
cjappl 43d0141
Fix python formatting errors
cjappl 06aa72d
Fix cpp style issues
cjappl 86191f1
PR: Delete python header comment
cjappl 47ea072
PR: Change main namespace name to __radsan
cjappl 26a571b
PR: Fix stack trace namespace
cjappl 71ae4a2
PR: Fix incorrect C++ style comments
cjappl 8dde886
PR: Prefix external API with dunderscores
cjappl 0a7062e
PR: Fix variable naming cases for variables, leave lambdas for now
cjappl 38d8436
PR: Fix style nit
cjappl ddab264
PR: Fix small style fallout
cjappl d12e0f1
Update comment and TU-local function style
davidtrevelyan 91bf6ed
PR: Remove too early inclusion of sanitizer common lit tests
cjappl c7a911e
Test failure: fix initialization of pthread_cond_t
cjappl 1e2322d
Test failure: Try again with initialization of pthread_cond_t
cjappl 3f976f8
Fix code formatting on unit test
cjappl da347d8
Ensure all pthread_cond_t are initialized in unit tests
cjappl 7710e55
Fix issue where CREAT flag was not properly passing mode (#23)
cjappl 7e430f8
Fix issue where fcntl was not using last arg correctly (#24)
cjappl 0ae584d
Introduce test fixture for temporary files (#25)
cjappl 91422bd
Clean out temp files in test fixture SetUp too
davidtrevelyan 4b491aa
Rename RADSan to RTSan
davidtrevelyan c717391
First working rtsan driver tests
cjappl 035d933
Add linux working test
cjappl 1b3bfad
Another test for openBSD
cjappl cf32e04
Add feature for realtime sanitizer, add incompatible sanitizers
cjappl e03a8f0
More incompatabilities added
cjappl 900632c
rtsan tests to fsanitize
cjappl df5f31b
Deleted rtsan.c
cjappl a375aca
Code formatting
cjappl 40862de
Fix python styling
cjappl 07d1ae5
PR: Get rid of clang components only leave compiler-rt
cjappl 7d531a7
PR: MaskRay comments
cjappl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,3 +67,7 @@ D: ThreadSanitizer | |
N: Bill Wendling | ||
E: [email protected] | ||
D: Profile runtime library | ||
|
||
N: Christopher Apple, David Trevelyan | ||
E: [email protected], [email protected] | ||
D: Realtime Sanitizer (RTSan) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,9 @@ 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_RTSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} | ||
${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} | ||
${LOONGARCH64}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was copied from ASAN, is this acceptable? We don't have all architectures to test, although we think that our interceptors are simple enough to work on any machine (no platform specific assembly in our code, for example) |
||
|
||
if(ANDROID) | ||
set(OS_NAME "Android") | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <rtsan/rtsan.h> | ||
#include <rtsan/rtsan_context.h> | ||
#include <rtsan/rtsan_interceptors.h> | ||
|
||
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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
//===--- 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include <rtsan/rtsan_context.h> | ||
|
||
#include <rtsan/rtsan_stack.h> | ||
|
||
#include <sanitizer_common/sanitizer_allocator_internal.h> | ||
#include <sanitizer_common/sanitizer_stacktrace.h> | ||
|
||
#include <new> | ||
#include <pthread.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
static pthread_key_t context_key; | ||
static pthread_once_t key_once = PTHREAD_ONCE_INIT; | ||
|
||
static void internalFree(void *ptr) { __sanitizer::InternalFree(ptr); } | ||
cjappl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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); | ||
__rtsan::Context *current_thread_context = | ||
static_cast<__rtsan::Context *>(pthread_getspecific(context_key)); | ||
if (current_thread_context == nullptr) { | ||
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); | ||
} | ||
|
||
return *current_thread_context; | ||
} | ||
|
||
/* | ||
This is a placeholder stub for a future feature that will allow | ||
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, | ||
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. | ||
*/ | ||
static void InvokeViolationDetectedAction() { exit(EXIT_FAILURE); } | ||
|
||
namespace __rtsan { | ||
cjappl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Context::Context() = default; | ||
|
||
void Context::RealtimePush() { realtime_depth++; } | ||
|
||
void Context::RealtimePop() { realtime_depth--; } | ||
|
||
void Context::BypassPush() { bypass_depth++; } | ||
|
||
void Context::BypassPop() { bypass_depth--; } | ||
|
||
void Context::ExpectNotRealtime(const char *intercepted_function_name) { | ||
if (InRealtimeContext() && !IsBypassed()) { | ||
BypassPush(); | ||
PrintDiagnostics(intercepted_function_name); | ||
InvokeViolationDetectedAction(); | ||
BypassPop(); | ||
} | ||
} | ||
|
||
bool Context::InRealtimeContext() const { return realtime_depth > 0; } | ||
|
||
bool Context::IsBypassed() const { return bypass_depth > 0; } | ||
|
||
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", | ||
intercepted_function_name); | ||
__rtsan::PrintStackTrace(); | ||
} | ||
|
||
Context &GetContextForThisThread() { return GetContextForThisThreadImpl(); } | ||
|
||
} // namespace __rtsan |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW @alexander-shaposhnikov NSAN is missing from here.