Skip to content

Commit

Permalink
#Centipede Add address-sanitized puzzles into the test workflow.
Browse files Browse the repository at this point in the history
Other tests would require more changes to be able to run with sanitizers. So we add only puzzles first.

PiperOrigin-RevId: 574999311
  • Loading branch information
xinhaoyuan authored and copybara-github committed Nov 2, 2023
1 parent d5c06cf commit 9bc5d45
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 81 deletions.
1 change: 0 additions & 1 deletion centipede/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,6 @@ RUNNER_SOURCES_NO_MAIN = [
"runner_interceptors.cc",
"runner_interface.h",
"runner_sancov.cc",
"runner_sanitizer.cc",
"shared_memory_blob_sequence.cc",
"shared_memory_blob_sequence.h",
]
Expand Down
2 changes: 1 addition & 1 deletion centipede/puzzles/puzzle.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def puzzle(name):
data = [
":" + name,
name + ".cc",
"@com_google_fuzztest//centipede",
"@com_google_fuzztest//centipede:centipede_uninstrumented",
"@com_google_fuzztest//centipede:test_util_sh",
],
)
2 changes: 1 addition & 1 deletion centipede/puzzles/run_puzzle.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ ls -la "$(dirname "$0")"
source "$(dirname "$0")/../test_util.sh"

readonly centipede_dir="$(centipede::get_centipede_test_srcdir)"
centipede::maybe_set_var_to_executable_path centipede "${centipede_dir}/centipede"
centipede::maybe_set_var_to_executable_path centipede "${centipede_dir}/centipede_uninstrumented"
readonly centipede

readonly target_name="$(basename "$0")"
Expand Down
2 changes: 2 additions & 0 deletions centipede/run_test_workflow.sh
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ bazel test "${BAZEL_ARGS[@]}" --local_test_jobs=1 --test_output=streamed \
centipede:all &&
bazel test "${BAZEL_ARGS[@]}" centipede/testing:instrumentation_test centipede/testing:runner_test &&
bazel test "${BAZEL_ARGS[@]}" centipede/puzzles:all
bazel test "${BAZEL_ARGS[@]}" --linkopt=-fsanitize=address --copt=-fsanitize=address centipede/puzzles:all

declare -ri exit_code=$?
set -e

Expand Down
7 changes: 4 additions & 3 deletions centipede/runner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -908,9 +908,10 @@ extern void ForkServerCallMeVeryEarly();
// * linker sees them and decides to drop runner_sancov.o.
extern void RunnerSancov();
[[maybe_unused]] auto fake_reference_for_runner_sancov = &RunnerSancov;
// Same for runner_sanitizer.cc.
extern void RunnerSanitizer();
[[maybe_unused]] auto fake_reference_for_runner_sanitizer = &RunnerSanitizer;
// Same for runner_interceptor.cc.
extern void RunnerInterceptor();
[[maybe_unused]] auto fake_reference_for_runner_interceptor =
&RunnerInterceptor;

GlobalRunnerState::GlobalRunnerState() {
// TODO(kcc): move some code from CentipedeRunnerMain() here so that it works
Expand Down
68 changes: 44 additions & 24 deletions centipede/runner_interceptors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,7 @@
// limitations under the License.

// Function interceptors for Centipede.
// Interceptors are disabled under ASAN/TSAN/MSAN because those sanitizers
// have their own conflicting interceptors.
// The typical usage of sanitizers with Centipede is via the --extra_binaries
// flag, where the sanitized binary does not produce coverage output and thus
// doesn't need (most of?) interceptors.
#if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER) && \
!defined(MEMORY_SANITIZER)

#include <dlfcn.h> // for dlsym()
#include <pthread.h>

Expand Down Expand Up @@ -77,19 +71,49 @@ int NormalizeCmpResult(int result) {

} // namespace

// Initialize original function pointers at the module startup. This may still
// be too late, since the functions may be used before this module is
// initialized. So, the interceptor may not assume that X_orig != nullptr for
// function X.
static auto memcmp_orig =
FuncAddr<int (*)(const void *s1, const void *s2, size_t n)>("memcmp");
static auto strcmp_orig =
FuncAddr<int (*)(const char *s1, const char *s2)>("strcmp");

// TODO(kcc): as we implement more functions like memcmp_fallback and
// length_of_common_prefix, move them into a separate module and unittest.
namespace centipede {
void RunnerInterceptor() {} // to be referenced in runner.cc
} // namespace centipede

// Fallback for the case memcmp_orig is null.
// A sanitizer-compatible way to intercept functions that are potentially
// intercepted by sanitizers, in which case the symbol __interceptor_X would be
// defined for intercepted function X. So we always forward an intercepted call
// to the sanitizer interceptor if it exists, and fall back to the next
// definition following dlsym.
//
// We define the X_orig pointers that are statically initialized to GetOrig_X()
// with the aforementioned logic to fill the pointers early, but they might
// still be too late. So the Centipede interceptors might need to handle the
// nullptr case and/or use REAL(X), which calls GetOrig_X() when needed. Also
// see compiler-rt/lib/interception/interception.h in the llvm-project source
// code.
//
// Note that since LLVM 17 it allows three interceptions (from the original
// binary, an external tool, and a sanitizer) to co-exist under a new scheme,
// while it is still compatible with the old way used here.
#define SANITIZER_INTERCEPTOR_NAME(orig_func_name) \
__interceptor_##orig_func_name
#define DECLARE_CENTIPEDE_ORIG_FUNC(ret_type, orig_func_name, args) \
extern "C" __attribute__((weak)) \
ret_type(SANITIZER_INTERCEPTOR_NAME(orig_func_name)) args; \
static decltype(&SANITIZER_INTERCEPTOR_NAME( \
orig_func_name)) GetOrig_##orig_func_name() { \
if (auto p = &SANITIZER_INTERCEPTOR_NAME(orig_func_name)) return p; \
return FuncAddr<decltype(&SANITIZER_INTERCEPTOR_NAME(orig_func_name))>( \
#orig_func_name); \
} \
static ret_type(*orig_func_name##_orig) args = GetOrig_##orig_func_name()
#define REAL(orig_func_name) \
(orig_func_name##_orig ? orig_func_name##_orig : GetOrig_##orig_func_name())

DECLARE_CENTIPEDE_ORIG_FUNC(int, memcmp,
(const void *s1, const void *s2, size_t n));
DECLARE_CENTIPEDE_ORIG_FUNC(int, strcmp, (const char *s1, const char *s2));
DECLARE_CENTIPEDE_ORIG_FUNC(int, pthread_create,
(pthread_t * thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg));

// Fallback for the case *cmp_orig is null.
// Will be executed several times at process startup, if at all.
static int memcmp_fallback(const void *s1, const void *s2, size_t n) {
const auto *p1 = static_cast<const uint8_t *>(s1);
Expand Down Expand Up @@ -131,12 +155,8 @@ extern "C" int strcmp(const char *s1, const char *s2) {
// Calls real pthread_create, but wraps the start_routine() in MyThreadStart.
extern "C" int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg) {
static auto pthread_create_orig =
FuncAddr<int (*)(pthread_t *, const pthread_attr_t *, void *(*)(void *),
void *)>("pthread_create");
// Wrap the arguments. Will be deleted in MyThreadStart.
auto *wrapped_args = new ThreadCreateArgs{start_routine, arg};
// Run the actual pthread_create.
return pthread_create_orig(thread, attr, MyThreadStart, wrapped_args);
return REAL(pthread_create)(thread, attr, MyThreadStart, wrapped_args);
}
#endif // not ASAN/TSAN/MSAN
50 changes: 0 additions & 50 deletions centipede/runner_sanitizer.cc

This file was deleted.

2 changes: 1 addition & 1 deletion centipede/testing/build_defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ affect all its transitive dependencies as well.
# Change the flags from the default ones to sancov:
# https://clang.llvm.org/docs/SanitizerCoverage.html.
def _sancov_transition_impl(settings, attr):
features_to_strip = ["asan", "tsan", "msan"]
features_to_strip = ["tsan", "msan"]
filtered_features = [
x
for x in settings["//command_line_option:features"]
Expand Down

0 comments on commit 9bc5d45

Please sign in to comment.