From 7df30e77d499e2416e74d67baa6b121f5d47d2a0 Mon Sep 17 00:00:00 2001 From: Mitch Phillips <31459023+hctim@users.noreply.github.com> Date: Fri, 9 Apr 2021 13:46:24 -0700 Subject: [PATCH] [ASan] Allow new/delete replacement by making interceptors weak ASan declares these functions as strongly-defined, which results in 'duplicate symbol' errors when trying to replace them in user code when linking the runtimes statically. Reviewed By: eugenis Differential Revision: https://reviews.llvm.org/D100220 --- compiler-rt/lib/asan/asan_new_delete.cpp | 2 +- .../asan/TestCases/replaceable_new_delete.cpp | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 compiler-rt/test/asan/TestCases/replaceable_new_delete.cpp diff --git a/compiler-rt/lib/asan/asan_new_delete.cpp b/compiler-rt/lib/asan/asan_new_delete.cpp index 5dfcc00fd5d14..92a8648452b07 100644 --- a/compiler-rt/lib/asan/asan_new_delete.cpp +++ b/compiler-rt/lib/asan/asan_new_delete.cpp @@ -45,7 +45,7 @@ COMMENT_EXPORT("??_V@YAXPAX@Z") // operator delete[] #endif #undef COMMENT_EXPORT #else -#define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE +#define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE #endif using namespace __asan; diff --git a/compiler-rt/test/asan/TestCases/replaceable_new_delete.cpp b/compiler-rt/test/asan/TestCases/replaceable_new_delete.cpp new file mode 100644 index 0000000000000..405daf3d1be88 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/replaceable_new_delete.cpp @@ -0,0 +1,28 @@ +// Ensure that operator new/delete are still replaceable. + +// RUN: %clangxx %s -o %t -fsanitize=address -shared-libsan && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx %s -o %t -fsanitize=address -static-libsan && not %run %t 2>&1 | FileCheck %s + +#include +#include +#include + +void *operator new[](size_t size) { + fprintf(stderr, "replaced new\n"); + return malloc(size); +} + +void operator delete[](void *ptr) noexcept { + fprintf(stderr, "replaced delete\n"); + return free(ptr); +} + +int main(int argc, char **argv) { + // CHECK: replaced new + char *x = new char[5]; + // CHECK: replaced delete + delete[] x; + // CHECK: ERROR: AddressSanitizer + *x = 13; + return 0; +}