Skip to content

Commit

Permalink
Revert "[Scudo] Make -fsanitize=scudo use standalone. Migrate tests."
Browse files Browse the repository at this point in the history
This reverts commit 6911114.

Broke the QEMU sanitizer bots due to a missing header dependency. This
actually needs to be fixed on the bot-side, but for now reverting this
patch until I can fix up the bot.
  • Loading branch information
hctim committed May 26, 2021
1 parent 73a1179 commit f7c5c0d
Show file tree
Hide file tree
Showing 37 changed files with 297 additions and 171 deletions.
17 changes: 13 additions & 4 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,10 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
SharedRuntimes.push_back("ubsan_standalone");
}
if (SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) {
SharedRuntimes.push_back("scudo_standalone");
if (SanArgs.requiresMinimalRuntime())
SharedRuntimes.push_back("scudo_minimal");
else
SharedRuntimes.push_back("scudo");
}
if (SanArgs.needsTsanRt() && SanArgs.linkRuntimes())
SharedRuntimes.push_back("tsan");
Expand Down Expand Up @@ -900,9 +903,15 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
RequiredSymbols.push_back("__sanitizer_stats_register");
}
if (!SanArgs.needsSharedRt() && SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) {
StaticRuntimes.push_back("scudo_standalone");
if (SanArgs.linkCXXRuntimes())
StaticRuntimes.push_back("scudo_standalone_cxx");
if (SanArgs.requiresMinimalRuntime()) {
StaticRuntimes.push_back("scudo_minimal");
if (SanArgs.linkCXXRuntimes())
StaticRuntimes.push_back("scudo_cxx_minimal");
} else {
StaticRuntimes.push_back("scudo");
if (SanArgs.linkCXXRuntimes())
StaticRuntimes.push_back("scudo_cxx");
}
}
}

Expand Down
6 changes: 3 additions & 3 deletions clang/test/Driver/fuchsia.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
// CHECK-SCUDO-X86: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
// CHECK-SCUDO-X86: "-fsanitize=safe-stack,scudo"
// CHECK-SCUDO-X86: "-pie"
// CHECK-SCUDO-X86: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo_standalone.so"
// CHECK-SCUDO-X86: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo.so"

// RUN: %clang %s -### --target=aarch64-unknown-fuchsia \
// RUN: -fsanitize=scudo 2>&1 \
Expand All @@ -163,7 +163,7 @@
// CHECK-SCUDO-AARCH64: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
// CHECK-SCUDO-AARCH64: "-fsanitize=shadow-call-stack,scudo"
// CHECK-SCUDO-AARCH64: "-pie"
// CHECK-SCUDO-AARCH64: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}aarch64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo_standalone.so"
// CHECK-SCUDO-AARCH64: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}aarch64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo.so"

// RUN: %clang %s -### --target=x86_64-unknown-fuchsia \
// RUN: -fsanitize=scudo -fPIC -shared 2>&1 \
Expand All @@ -172,7 +172,7 @@
// RUN: | FileCheck %s -check-prefix=CHECK-SCUDO-SHARED
// CHECK-SCUDO-SHARED: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
// CHECK-SCUDO-SHARED: "-fsanitize=safe-stack,scudo"
// CHECK-SCUDO-SHARED: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo_standalone.so"
// CHECK-SCUDO-SHARED: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo.so"

// RUN: %clang %s -### --target=aarch64-unknown-fuchsia \
// RUN: -fsanitize=leak 2>&1 \
Expand Down
20 changes: 15 additions & 5 deletions clang/test/Driver/sanitizer-ld.c
Original file line number Diff line number Diff line change
Expand Up @@ -773,11 +773,21 @@
// RUN: | FileCheck --check-prefix=CHECK-SCUDO-LINUX %s
// CHECK-SCUDO-LINUX: "{{.*}}ld{{(.exe)?}}"
// CHECK-SCUDO-LINUX: "-pie"
// CHECK-SCUDO-LINUX: "--whole-archive" "{{.*}}libclang_rt.scudo_standalone-i386.a" "--no-whole-archive"
// CHECK-SCUDO-LINUX: "--whole-archive" "{{.*}}libclang_rt.scudo-i386.a" "--no-whole-archive"
// CHECK-SCUDO-LINUX-NOT: "-lstdc++"
// CHECK-SCUDO-LINUX: "-lpthread"
// CHECK-SCUDO-LINUX: "-ldl"

// RUN: %clang -fsanitize=scudo -fsanitize-minimal-runtime %s -### -o %t.o 2>&1 \
// RUN: -target i386-unknown-linux -fuse-ld=ld \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-SCUDO-MINIMAL-LINUX %s
// CHECK-SCUDO-MINIMAL-LINUX: "{{.*}}ld{{(.exe)?}}"
// CHECK-SCUDO-MINIMAL-LINUX: "-pie"
// CHECK-SCUDO-MINIMAL-LINUX: "--whole-archive" "{{.*}}libclang_rt.scudo_minimal-i386.a" "--no-whole-archive"
// CHECK-SCUDO-MINIMAL-LINUX: "-lpthread"

// RUN: %clang -no-canonical-prefixes %s -### -o %t.so -shared 2>&1 \
// RUN: -target i386-unknown-linux -fuse-ld=ld -fsanitize=scudo -shared-libsan \
// RUN: -resource-dir=%S/Inputs/resource_dir \
Expand All @@ -786,8 +796,8 @@
//
// CHECK-SCUDO-SHARED-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-SCUDO-SHARED-LINUX-NOT: "-lc"
// CHECK-SCUDO-SHARED-LINUX-NOT: libclang_rt.scudo_standalone-i386.a"
// CHECK-SCUDO-SHARED-LINUX: libclang_rt.scudo_standalone-i386.so"
// CHECK-SCUDO-SHARED-LINUX-NOT: libclang_rt.scudo-i386.a"
// CHECK-SCUDO-SHARED-LINUX: libclang_rt.scudo-i386.so"
// CHECK-SCUDO-SHARED-LINUX-NOT: "-lpthread"
// CHECK-SCUDO-SHARED-LINUX-NOT: "-lrt"
// CHECK-SCUDO-SHARED-LINUX-NOT: "-ldl"
Expand All @@ -803,7 +813,7 @@
// CHECK-SCUDO-ANDROID-NOT: "-lc"
// CHECK-SCUDO-ANDROID: "-pie"
// CHECK-SCUDO-ANDROID-NOT: "-lpthread"
// CHECK-SCUDO-ANDROID: libclang_rt.scudo_standalone-arm-android.so"
// CHECK-SCUDO-ANDROID: libclang_rt.scudo-arm-android.so"
// CHECK-SCUDO-ANDROID-NOT: "-lpthread"

// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
Expand All @@ -813,7 +823,7 @@
// RUN: | FileCheck --check-prefix=CHECK-SCUDO-ANDROID-STATIC %s
// CHECK-SCUDO-ANDROID-STATIC: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
// CHECK-SCUDO-ANDROID-STATIC: "-pie"
// CHECK-SCUDO-ANDROID-STATIC: "--whole-archive" "{{.*}}libclang_rt.scudo_standalone-arm-android.a" "--no-whole-archive"
// CHECK-SCUDO-ANDROID-STATIC: "--whole-archive" "{{.*}}libclang_rt.scudo-arm-android.a" "--no-whole-archive"
// CHECK-SCUDO-ANDROID-STATIC-NOT: "-lstdc++"
// CHECK-SCUDO-ANDROID-STATIC-NOT: "-lpthread"
// CHECK-SCUDO-ANDROID-STATIC-NOT: "-lrt"
Expand Down
25 changes: 0 additions & 25 deletions compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,6 @@ struct nothrow_t {};
enum class align_val_t : size_t {};
} // namespace std

// It's not valid for a non-throwing non-noreturn operator new to return
// nullptr. In these cases, just terminate.
#define CHECK_ALIGN_NORETURN(align) \
do { \
scudo::uptr alignment = static_cast<scudo::uptr>(align); \
if (UNLIKELY(!scudo::isPowerOfTwo(alignment))) { \
scudo::reportAlignmentNotPowerOfTwo(alignment); \
} \
} while (0)

#define CHECK_ALIGN(align) \
do { \
scudo::uptr alignment = static_cast<scudo::uptr>(align); \
if (UNLIKELY(!scudo::isPowerOfTwo(alignment))) { \
if (Allocator.canReturnNull()) { \
return nullptr; \
} \
scudo::reportAlignmentNotPowerOfTwo(alignment); \
} \
} while (0)

INTERFACE WEAK void *operator new(size_t size) {
return Allocator.allocate(size, scudo::Chunk::Origin::New);
}
Expand All @@ -59,24 +38,20 @@ INTERFACE WEAK void *operator new[](size_t size,
return Allocator.allocate(size, scudo::Chunk::Origin::NewArray);
}
INTERFACE WEAK void *operator new(size_t size, std::align_val_t align) {
CHECK_ALIGN_NORETURN(align);
return Allocator.allocate(size, scudo::Chunk::Origin::New,
static_cast<scudo::uptr>(align));
}
INTERFACE WEAK void *operator new[](size_t size, std::align_val_t align) {
CHECK_ALIGN_NORETURN(align);
return Allocator.allocate(size, scudo::Chunk::Origin::NewArray,
static_cast<scudo::uptr>(align));
}
INTERFACE WEAK void *operator new(size_t size, std::align_val_t align,
std::nothrow_t const &) NOEXCEPT {
CHECK_ALIGN(align);
return Allocator.allocate(size, scudo::Chunk::Origin::New,
static_cast<scudo::uptr>(align));
}
INTERFACE WEAK void *operator new[](size_t size, std::align_val_t align,
std::nothrow_t const &) NOEXCEPT {
CHECK_ALIGN(align);
return Allocator.allocate(size, scudo::Chunk::Origin::NewArray,
static_cast<scudo::uptr>(align));
}
Expand Down
34 changes: 34 additions & 0 deletions compiler-rt/test/scudo/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,35 @@
set(SCUDO_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(SCUDO_LIT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})

set(SCUDO_TESTSUITES)

set(SCUDO_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
if(NOT COMPILER_RT_STANDALONE_BUILD)
list(APPEND SCUDO_TEST_DEPS scudo)
endif()

configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
)

set(SCUDO_TEST_ARCH ${SCUDO_SUPPORTED_ARCH})
foreach(arch ${SCUDO_TEST_ARCH})
set(SCUDO_TEST_TARGET_ARCH ${arch})
string(TOLOWER "-${arch}" SCUDO_TEST_CONFIG_SUFFIX)
get_test_cc_for_arch(${arch} SCUDO_TEST_TARGET_CC SCUDO_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 SCUDO_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
endforeach()

add_subdirectory(standalone)

add_lit_testsuite(check-scudo "Running the Scudo Hardened Allocator tests"
${SCUDO_TESTSUITES}
DEPENDS ${SCUDO_TEST_DEPS})
set_target_properties(check-scudo PROPERTIES FOLDER "Compiler-RT Misc")
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %clangxx_scudo -std=c++17 -faligned-allocation %s -o %t
// RUN: %clangxx_scudo -std=c++1z -faligned-allocation %s -o %t
// RUN: %run %t valid 2>&1
// RUN: %env_scudo_opts=may_return_null=1 %run %t invalid 2>&1
// RUN: %env_scudo_opts=may_return_null=0 not --crash %run %t invalid 2>&1 | FileCheck %s
// RUN: %env_scudo_opts=allocator_may_return_null=1 %run %t invalid 2>&1
// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t invalid 2>&1 | FileCheck %s

// Tests that the C++17 aligned new/delete operators are working as expected.
// Currently we do not check the consistency of the alignment on deallocation,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %clang_scudo %s -o %t
// RUN: not --crash %run %t pointers 2>&1 | FileCheck %s
// RUN: not %run %t pointers 2>&1 | FileCheck %s

// Tests that a non MinAlignment aligned pointer will trigger the associated
// error on deallocation.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// RUN: %clang_scudo %s -O2 -o %t
// RUN: %env_scudo_opts="QuarantineChunksUpToSize=0" %run %t 2>&1

// This test attempts to reproduce a race condition in the original Scudo in the
// deallocation path when bypassing the Quarantine. The old behavior was to
// zero-out the chunk header after checking its checksum, state & various other
// things, but that left a window during which 2 (or more) threads could
// deallocate the same chunk, with a net result of having said chunk present in
// those distinct thread caches.
// This test attempts to reproduce a race condition in the deallocation path
// when bypassing the Quarantine. The old behavior was to zero-out the chunk
// header after checking its checksum, state & various other things, but that
// left a window during which 2 (or more) threads could deallocate the same
// chunk, with a net result of having said chunk present in those distinct
// thread caches.

// A passing test means all the children died with an error. The failing
// scenario involves winning a race, so repro can be scarce.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %clangxx_scudo %s -o %t
// RUN: not --crash %run %t malloc 2>&1 | FileCheck %s
// RUN: not --crash %run %t new 2>&1 | FileCheck %s
// RUN: not --crash %run %t newarray 2>&1 | FileCheck %s
// RUN: not %run %t malloc 2>&1 | FileCheck %s
// RUN: not %run %t new 2>&1 | FileCheck %s
// RUN: not %run %t newarray 2>&1 | FileCheck %s

// Tests double-free error on pointers allocated with different allocation
// functions.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
// Test various -fsanitize= additional flags combinations.

// RUN: %clang_scudo %s -o %t
// RUN: not --crash %run %t 2>&1 | FileCheck %s
// RUN: not %run %t 2>&1 | FileCheck %s

// RUN: %clang_scudo -shared-libsan %s -o %t
// RUN: env LD_LIBRARY_PATH=`dirname %shared_libscudo`:$LD_LIBRARY_PATH not --crash %run %t 2>&1 | FileCheck %s
// RUN: env LD_LIBRARY_PATH=`dirname %shared_libscudo`:$LD_LIBRARY_PATH not %run %t 2>&1 | FileCheck %s
// RUN: %clang_scudo -shared-libsan -fsanitize-minimal-runtime %s -o %t
// RUN: env LD_LIBRARY_PATH=`dirname %shared_minlibscudo`:$LD_LIBRARY_PATH not %run %t 2>&1 | FileCheck %s

// RUN: %clang_scudo -static-libsan %s -o %t
// RUN: not --crash %run %t 2>&1 | FileCheck %s
// RUN: not %run %t 2>&1 | FileCheck %s
// RUN: %clang_scudo -static-libsan -fsanitize-minimal-runtime %s -o %t
// RUN: not --crash %run %t 2>&1 | FileCheck %s
// RUN: not %run %t 2>&1 | FileCheck %s

#include <assert.h>
#include <stdlib.h>
Expand Down
91 changes: 91 additions & 0 deletions compiler-rt/test/scudo/interface.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// RUN: %clangxx_scudo %s -lstdc++ -o %t
// RUN: %run %t ownership 2>&1
// RUN: %run %t ownership-and-size 2>&1
// RUN: %run %t heap-size 2>&1
// RUN: %env_scudo_opts="allocator_may_return_null=1" %run %t soft-limit 2>&1
// RUN: %env_scudo_opts="allocator_may_return_null=1" not %run %t hard-limit 2>&1

// Tests that the sanitizer interface functions behave appropriately.

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <vector>

#include <sanitizer/allocator_interface.h>
#include <sanitizer/scudo_interface.h>

int main(int argc, char **argv) {
assert(argc == 2);

if (!strcmp(argv[1], "ownership")) {
// Ensures that __sanitizer_get_ownership can be called before any other
// allocator function, and that it behaves properly on a pointer not owned
// by us.
assert(!__sanitizer_get_ownership(argv));
}
if (!strcmp(argv[1], "ownership-and-size")) {
// Tests that __sanitizer_get_ownership and __sanitizer_get_allocated_size
// behave properly on chunks allocated by the Primary and Secondary.
void *p;
std::vector<ssize_t> sizes{1, 8, 16, 32, 1024, 32768,
1 << 16, 1 << 17, 1 << 20, 1 << 24};
for (size_t size : sizes) {
p = malloc(size);
assert(p);
assert(__sanitizer_get_ownership(p));
assert(__sanitizer_get_allocated_size(p) >= size);
free(p);
}
}
if (!strcmp(argv[1], "heap-size")) {
// Ensures that __sanitizer_get_heap_size can be called before any other
// allocator function.
assert(__sanitizer_get_heap_size() >= 0);
}
if (!strcmp(argv[1], "soft-limit")) {
// Verifies that setting the soft RSS limit at runtime works as expected.
std::vector<void *> pointers;
size_t size = 1 << 19; // 512Kb
for (int i = 0; i < 5; i++) {
void *p = malloc(size);
memset(p, 0, size);
pointers.push_back(p);
}
// Set the soft RSS limit to 1Mb.
__scudo_set_rss_limit(1, 0);
usleep(20000);
// The following allocation should return NULL.
void *p = malloc(size);
assert(!p);
// Remove the soft RSS limit.
__scudo_set_rss_limit(0, 0);
// The following allocation should succeed.
p = malloc(size);
assert(p);
free(p);
while (!pointers.empty()) {
free(pointers.back());
pointers.pop_back();
}
}
if (!strcmp(argv[1], "hard-limit")) {
// Verifies that setting the hard RSS limit at runtime works as expected.
std::vector<void *> pointers;
size_t size = 1 << 19; // 512Kb
for (int i = 0; i < 5; i++) {
void *p = malloc(size);
memset(p, 0, size);
pointers.push_back(p);
}
// Set the hard RSS limit to 1Mb
__scudo_set_rss_limit(1, 1);
usleep(20000);
// The following should trigger our death.
void *p = malloc(size);
}

return 0;
}
Loading

0 comments on commit f7c5c0d

Please sign in to comment.