diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -809,10 +809,7 @@ SharedRuntimes.push_back("ubsan_standalone"); } if (SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) { - if (SanArgs.requiresMinimalRuntime()) - SharedRuntimes.push_back("scudo_minimal"); - else - SharedRuntimes.push_back("scudo"); + SharedRuntimes.push_back("scudo_standalone"); } if (SanArgs.needsTsanRt() && SanArgs.linkRuntimes()) SharedRuntimes.push_back("tsan"); @@ -903,15 +900,9 @@ RequiredSymbols.push_back("__sanitizer_stats_register"); } if (!SanArgs.needsSharedRt() && SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) { - 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"); - } + StaticRuntimes.push_back("scudo_standalone"); + if (SanArgs.linkCXXRuntimes()) + StaticRuntimes.push_back("scudo_standalone_cxx"); } } diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-fuchsia/libclang_rt.scudo.so b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-fuchsia/libclang_rt.scudo_standalone.so rename from clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-fuchsia/libclang_rt.scudo.so rename to clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-fuchsia/libclang_rt.scudo_standalone.so diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-unknown-fuchsia/libclang_rt.scudo.so b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-unknown-fuchsia/libclang_rt.scudo_standalone.so rename from clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-unknown-fuchsia/libclang_rt.scudo.so rename to clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-unknown-fuchsia/libclang_rt.scudo_standalone.so diff --git a/clang/test/Driver/fuchsia.c b/clang/test/Driver/fuchsia.c --- a/clang/test/Driver/fuchsia.c +++ b/clang/test/Driver/fuchsia.c @@ -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.so" +// CHECK-SCUDO-X86: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo_standalone.so" // RUN: %clang %s -### --target=aarch64-unknown-fuchsia \ // RUN: -fsanitize=scudo 2>&1 \ @@ -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.so" +// CHECK-SCUDO-AARCH64: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}aarch64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo_standalone.so" // RUN: %clang %s -### --target=x86_64-unknown-fuchsia \ // RUN: -fsanitize=scudo -fPIC -shared 2>&1 \ @@ -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.so" +// CHECK-SCUDO-SHARED: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}libclang_rt.scudo_standalone.so" // RUN: %clang %s -### --target=aarch64-unknown-fuchsia \ // RUN: -fsanitize=leak 2>&1 \ diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c --- a/clang/test/Driver/sanitizer-ld.c +++ b/clang/test/Driver/sanitizer-ld.c @@ -773,21 +773,11 @@ // 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-i386.a" "--no-whole-archive" +// CHECK-SCUDO-LINUX: "--whole-archive" "{{.*}}libclang_rt.scudo_standalone-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 \ @@ -796,8 +786,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-i386.a" -// CHECK-SCUDO-SHARED-LINUX: libclang_rt.scudo-i386.so" +// 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: "-lpthread" // CHECK-SCUDO-SHARED-LINUX-NOT: "-lrt" // CHECK-SCUDO-SHARED-LINUX-NOT: "-ldl" @@ -813,7 +803,7 @@ // CHECK-SCUDO-ANDROID-NOT: "-lc" // CHECK-SCUDO-ANDROID: "-pie" // CHECK-SCUDO-ANDROID-NOT: "-lpthread" -// CHECK-SCUDO-ANDROID: libclang_rt.scudo-arm-android.so" +// CHECK-SCUDO-ANDROID: libclang_rt.scudo_standalone-arm-android.so" // CHECK-SCUDO-ANDROID-NOT: "-lpthread" // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ @@ -823,7 +813,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-arm-android.a" "--no-whole-archive" +// CHECK-SCUDO-ANDROID-STATIC: "--whole-archive" "{{.*}}libclang_rt.scudo_standalone-arm-android.a" "--no-whole-archive" // CHECK-SCUDO-ANDROID-STATIC-NOT: "-lstdc++" // CHECK-SCUDO-ANDROID-STATIC-NOT: "-lpthread" // CHECK-SCUDO-ANDROID-STATIC-NOT: "-lrt" diff --git a/compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp b/compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp --- a/compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp +++ b/compiler-rt/lib/scudo/standalone/wrappers_cpp.cpp @@ -23,6 +23,27 @@ 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(align); \ + if (UNLIKELY(!scudo::isPowerOfTwo(alignment))) { \ + scudo::reportAlignmentNotPowerOfTwo(alignment); \ + } \ + } while (0) + +#define CHECK_ALIGN(align) \ + do { \ + scudo::uptr alignment = static_cast(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); } @@ -38,20 +59,24 @@ 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(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(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(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(align)); } diff --git a/compiler-rt/test/scudo/CMakeLists.txt b/compiler-rt/test/scudo/CMakeLists.txt --- a/compiler-rt/test/scudo/CMakeLists.txt +++ b/compiler-rt/test/scudo/CMakeLists.txt @@ -1,35 +1 @@ -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") diff --git a/compiler-rt/test/scudo/interface.cpp b/compiler-rt/test/scudo/interface.cpp deleted file mode 100644 --- a/compiler-rt/test/scudo/interface.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// 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 -#include -#include -#include - -#include - -#include -#include - -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 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 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 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; -} diff --git a/compiler-rt/test/scudo/lit.cfg.py b/compiler-rt/test/scudo/lit.cfg.py deleted file mode 100644 --- a/compiler-rt/test/scudo/lit.cfg.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- Python -*- - -import os - -# Setup config name. -config.name = 'Scudo' + config.name_suffix - -# Setup source root. -config.test_source_root = os.path.dirname(__file__) - -# Path to the shared library -shared_libscudo = os.path.join(config.compiler_rt_libdir, "libclang_rt.scudo%s.so" % config.target_suffix) -shared_minlibscudo = os.path.join(config.compiler_rt_libdir, "libclang_rt.scudo_minimal%s.so" % config.target_suffix) - -# Test suffixes. -config.suffixes = ['.c', '.cpp', '.test'] - -# C & CXX flags. -c_flags = ([config.target_cflags] + - ["-pthread", - "-fPIE", - "-pie", - "-O0", - "-UNDEBUG", - "-ldl", - "-Wl,--gc-sections"]) - -# Android doesn't want -lrt. -if not config.android: - c_flags += ["-lrt"] - -cxx_flags = (c_flags + config.cxx_mode_flags + ["-std=c++11"]) - -scudo_flags = ["-fsanitize=scudo"] - -def build_invocation(compile_flags): - return " " + " ".join([config.clang] + compile_flags) + " " - -# Add substitutions. -config.substitutions.append(("%clang ", build_invocation(c_flags))) -config.substitutions.append(("%clang_scudo ", build_invocation(c_flags + scudo_flags))) -config.substitutions.append(("%clangxx_scudo ", build_invocation(cxx_flags + scudo_flags))) -config.substitutions.append(("%shared_libscudo", shared_libscudo)) -config.substitutions.append(("%shared_minlibscudo", shared_minlibscudo)) - -# Platform-specific default SCUDO_OPTIONS for lit tests. -default_scudo_opts = '' -if config.android: - # Android defaults to abort_on_error=1, which doesn't work for us. - default_scudo_opts = 'abort_on_error=0' - -# Disable GWP-ASan for scudo internal tests. -if config.gwp_asan: - config.environment['GWP_ASAN_OPTIONS'] = 'Enabled=0' - -if default_scudo_opts: - config.environment['SCUDO_OPTIONS'] = default_scudo_opts - default_scudo_opts += ':' -config.substitutions.append(('%env_scudo_opts=', - 'env SCUDO_OPTIONS=' + default_scudo_opts)) - -# Hardened Allocator tests are currently supported on Linux only. -if config.host_os not in ['Linux']: - config.unsupported = True diff --git a/compiler-rt/test/scudo/lit.site.cfg.py.in b/compiler-rt/test/scudo/lit.site.cfg.py.in deleted file mode 100644 --- a/compiler-rt/test/scudo/lit.site.cfg.py.in +++ /dev/null @@ -1,11 +0,0 @@ -@LIT_SITE_CFG_IN_HEADER@ - -config.name_suffix = "@SCUDO_TEST_CONFIG_SUFFIX@" -config.target_arch = "@SCUDO_TEST_TARGET_ARCH@" -config.target_cflags = "@SCUDO_TEST_TARGET_CFLAGS@" - -# Load common config for all compiler-rt lit tests. -lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured") - -# Load tool-specific config that would do the real work. -lit_config.load_config(config, "@SCUDO_LIT_SOURCE_DIR@/lit.cfg.py") diff --git a/compiler-rt/test/scudo/standalone/CMakeLists.txt b/compiler-rt/test/scudo/standalone/CMakeLists.txt --- a/compiler-rt/test/scudo/standalone/CMakeLists.txt +++ b/compiler-rt/test/scudo/standalone/CMakeLists.txt @@ -1,4 +1,22 @@ +set(SCUDO_STANDALONE_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(SCUDO_STANDALONE_LIT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) +set(SCUDO_STANDALONE_TESTSUITES) +set(SCUDO_STANDALONE_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} scudo_standalone) + if(COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_HAS_SCUDO_STANDALONE) + foreach(arch ${SCUDO_STANDALONE_SUPPORTED_ARCH}) + set(SCUDO_STANDALONE_TEST_TARGET_ARCH ${arch}) + string(TOLOWER "-${arch}" SCUDO_STANDALONE_TEST_CONFIG_SUFFIX) + get_target_flags_for_arch(${arch} SCUDO_STANDALONE_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_STANDALONE_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}) + endforeach() + configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.site.cfg.py.in ${CMAKE_CURRENT_BINARY_DIR}/unit/lit.site.cfg.py) diff --git a/compiler-rt/test/scudo/aligned-new.cpp b/compiler-rt/test/scudo/standalone/aligned-new.cpp rename from compiler-rt/test/scudo/aligned-new.cpp rename to compiler-rt/test/scudo/standalone/aligned-new.cpp --- a/compiler-rt/test/scudo/aligned-new.cpp +++ b/compiler-rt/test/scudo/standalone/aligned-new.cpp @@ -1,7 +1,7 @@ -// RUN: %clangxx_scudo -std=c++1z -faligned-allocation %s -o %t +// RUN: %clangxx_scudo -std=c++17 -faligned-allocation %s -o %t // RUN: %run %t valid 2>&1 -// 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 +// 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 // 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, diff --git a/compiler-rt/test/scudo/alignment.c b/compiler-rt/test/scudo/standalone/alignment.c rename from compiler-rt/test/scudo/alignment.c rename to compiler-rt/test/scudo/standalone/alignment.c --- a/compiler-rt/test/scudo/alignment.c +++ b/compiler-rt/test/scudo/standalone/alignment.c @@ -1,5 +1,5 @@ // RUN: %clang_scudo %s -o %t -// RUN: not %run %t pointers 2>&1 | FileCheck %s +// RUN: not --crash %run %t pointers 2>&1 | FileCheck %s // Tests that a non MinAlignment aligned pointer will trigger the associated // error on deallocation. diff --git a/compiler-rt/test/scudo/dealloc-race.c b/compiler-rt/test/scudo/standalone/dealloc-race.c rename from compiler-rt/test/scudo/dealloc-race.c rename to compiler-rt/test/scudo/standalone/dealloc-race.c --- a/compiler-rt/test/scudo/dealloc-race.c +++ b/compiler-rt/test/scudo/standalone/dealloc-race.c @@ -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 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 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. // A passing test means all the children died with an error. The failing // scenario involves winning a race, so repro can be scarce. diff --git a/compiler-rt/test/scudo/double-free.cpp b/compiler-rt/test/scudo/standalone/double-free.cpp rename from compiler-rt/test/scudo/double-free.cpp rename to compiler-rt/test/scudo/standalone/double-free.cpp --- a/compiler-rt/test/scudo/double-free.cpp +++ b/compiler-rt/test/scudo/standalone/double-free.cpp @@ -1,7 +1,7 @@ // RUN: %clangxx_scudo %s -o %t -// 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 +// 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 // Tests double-free error on pointers allocated with different allocation // functions. diff --git a/compiler-rt/test/scudo/fsanitize.c b/compiler-rt/test/scudo/standalone/fsanitize.c rename from compiler-rt/test/scudo/fsanitize.c rename to compiler-rt/test/scudo/standalone/fsanitize.c --- a/compiler-rt/test/scudo/fsanitize.c +++ b/compiler-rt/test/scudo/standalone/fsanitize.c @@ -1,17 +1,15 @@ // Test various -fsanitize= additional flags combinations. // RUN: %clang_scudo %s -o %t -// RUN: not %run %t 2>&1 | FileCheck %s +// RUN: not --crash %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 %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: env LD_LIBRARY_PATH=`dirname %shared_libscudo`:$LD_LIBRARY_PATH not --crash %run %t 2>&1 | FileCheck %s // RUN: %clang_scudo -static-libsan %s -o %t -// RUN: not %run %t 2>&1 | FileCheck %s +// RUN: not --crash %run %t 2>&1 | FileCheck %s // RUN: %clang_scudo -static-libsan -fsanitize-minimal-runtime %s -o %t -// RUN: not %run %t 2>&1 | FileCheck %s +// RUN: not --crash %run %t 2>&1 | FileCheck %s #include #include diff --git a/compiler-rt/test/scudo/overflow.c b/compiler-rt/test/scudo/standalone/lit-unmigrated/overflow.c rename from compiler-rt/test/scudo/overflow.c rename to compiler-rt/test/scudo/standalone/lit-unmigrated/overflow.c diff --git a/compiler-rt/test/scudo/quarantine.c b/compiler-rt/test/scudo/standalone/lit-unmigrated/quarantine.c rename from compiler-rt/test/scudo/quarantine.c rename to compiler-rt/test/scudo/standalone/lit-unmigrated/quarantine.c diff --git a/compiler-rt/test/scudo/realloc.cpp b/compiler-rt/test/scudo/standalone/lit-unmigrated/realloc.cpp rename from compiler-rt/test/scudo/realloc.cpp rename to compiler-rt/test/scudo/standalone/lit-unmigrated/realloc.cpp --- a/compiler-rt/test/scudo/realloc.cpp +++ b/compiler-rt/test/scudo/standalone/lit-unmigrated/realloc.cpp @@ -37,7 +37,7 @@ free(p); size += 16; p = malloc(size); - usable_size = __sanitizer_get_allocated_size(p); + usable_size = malloc_usable_size(p); assert(usable_size >= size); } while (usable_size == size); for (int i = 0; i < usable_size; i++) @@ -58,7 +58,7 @@ if (!strcmp(argv[1], "pointers")) { old_p = p = realloc(nullptr, size); assert(p); - size = __sanitizer_get_allocated_size(p); + size = malloc_usable_size(p); // Our realloc implementation will return the same pointer if the size // requested is lower than or equal to the usable size of the associated // chunk. diff --git a/compiler-rt/test/scudo/rss.c b/compiler-rt/test/scudo/standalone/lit-unmigrated/rss.c rename from compiler-rt/test/scudo/rss.c rename to compiler-rt/test/scudo/standalone/lit-unmigrated/rss.c diff --git a/compiler-rt/test/scudo/secondary.c b/compiler-rt/test/scudo/standalone/lit-unmigrated/secondary.c rename from compiler-rt/test/scudo/secondary.c rename to compiler-rt/test/scudo/standalone/lit-unmigrated/secondary.c diff --git a/compiler-rt/test/scudo/sizes.cpp b/compiler-rt/test/scudo/standalone/lit-unmigrated/sizes.cpp rename from compiler-rt/test/scudo/sizes.cpp rename to compiler-rt/test/scudo/standalone/lit-unmigrated/sizes.cpp --- a/compiler-rt/test/scudo/sizes.cpp +++ b/compiler-rt/test/scudo/standalone/lit-unmigrated/sizes.cpp @@ -1,13 +1,13 @@ // RUN: %clangxx_scudo %s -lstdc++ -o %t -// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-max -// RUN: %env_scudo_opts=allocator_may_return_null=1 %run %t malloc 2>&1 -// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-calloc -// RUN: %env_scudo_opts=allocator_may_return_null=1 %run %t calloc 2>&1 -// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t new 2>&1 | FileCheck %s --check-prefix=CHECK-max -// RUN: %env_scudo_opts=allocator_may_return_null=1 not %run %t new 2>&1 | FileCheck %s --check-prefix=CHECK-oom -// RUN: %env_scudo_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 | FileCheck %s --check-prefix=CHECK-max -// RUN: %env_scudo_opts=allocator_may_return_null=1 %run %t new-nothrow 2>&1 -// RUN: %run %t usable 2>&1 +// RUN: %env_scudo_opts=may_return_null=0 not --crash %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-max +// RUN: %env_scudo_opts=may_return_null=1 %run %t malloc 2>&1 +// RUNZ: %env_scudo_opts=may_return_null=0 not --crash %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-calloc +// RUNZ: %env_scudo_opts=may_return_null=1 %run %t calloc 2>&1 +// RUNZ: %env_scudo_opts=may_return_null=0 not --crash %run %t new 2>&1 | FileCheck %s --check-prefix=CHECK-max +// RUNZ: %env_scudo_opts=may_return_null=1 not --crash %run %t new 2>&1 | FileCheck %s --check-prefix=CHECK-oom +// RUNZ: %env_scudo_opts=may_return_null=0 not --crash %run %t new-nothrow 2>&1 | FileCheck %s --check-prefix=CHECK-max +// RUNZ: %env_scudo_opts=may_return_null=1 %run %t new-nothrow 2>&1 +// RUNZ: %run %t usable 2>&1 // Tests for various edge cases related to sizes, notably the maximum size the // allocator can allocate. Tests that an integer overflow in the parameters of @@ -54,12 +54,12 @@ // Playing with the actual usable size of a chunk. void *p = malloc(1007); assert(p); - size_t size = __sanitizer_get_allocated_size(p); + size_t size = malloc_usable_size(p); assert(size >= 1007); memset(p, 'A', size); p = realloc(p, 2014); assert(p); - size = __sanitizer_get_allocated_size(p); + size = malloc_usable_size(p); assert(size >= 2014); memset(p, 'B', size); free(p); diff --git a/compiler-rt/test/scudo/threads.c b/compiler-rt/test/scudo/standalone/lit-unmigrated/threads.c rename from compiler-rt/test/scudo/threads.c rename to compiler-rt/test/scudo/standalone/lit-unmigrated/threads.c diff --git a/compiler-rt/test/scudo/valloc.c b/compiler-rt/test/scudo/standalone/lit-unmigrated/valloc.c rename from compiler-rt/test/scudo/valloc.c rename to compiler-rt/test/scudo/standalone/lit-unmigrated/valloc.c --- a/compiler-rt/test/scudo/valloc.c +++ b/compiler-rt/test/scudo/standalone/lit-unmigrated/valloc.c @@ -1,7 +1,7 @@ // RUN: %clang_scudo %s -o %t -// RUN: %run %t valid 2>&1 -// RUN: not %run %t invalid 2>&1 | FileCheck %s -// RUN: %env_scudo_opts=allocator_may_return_null=1 %run %t invalid 2>&1 +// RUN: %run %t valid 2>&1 +// RUN: not --crash %run %t invalid 2>&1 | FileCheck %s +// RUNX: %env_scudo_opts=may_return_null=1 %run %t invalid 2>&1 // UNSUPPORTED: android // Tests that valloc and pvalloc work as intended. diff --git a/compiler-rt/test/scudo/standalone/lit.cfg.py b/compiler-rt/test/scudo/standalone/lit.cfg.py new file mode 100644 --- /dev/null +++ b/compiler-rt/test/scudo/standalone/lit.cfg.py @@ -0,0 +1,49 @@ +# -*- Python -*- + +import os + +# Setup config name. +config.name = 'ScudoStandalone' + config.name_suffix + +# Setup source root. +config.test_source_root = os.path.dirname(__file__) + +# Path to the shared library +shared_libscudo = os.path.join(config.compiler_rt_libdir, + "libclang_rt.scudo_standalone%s.so" % config.target_suffix) + +# Test suffixes. +config.suffixes = ['.c', '.cpp'] +config.excludes = ['lit-unmigrated'] + +# C & CXX flags. For cross-compiling, make sure that we pick up the +# libclang_rt.scudo_standalone libraries from the working build directory (using +# `-resource-dir`), rather than the host compiler. +c_flags = ([config.target_cflags] + + ["-pthread", "-fPIE", "-pie", "-O0", "-UNDEBUG", "-Wl,--gc-sections", + "-resource-dir=" + config.compiler_rt_libdir + "/../../"]) + +cxx_flags = (c_flags + config.cxx_mode_flags + ["-std=c++14"]) + +scudo_flags = ["-fsanitize=scudo"] + +def build_invocation(compile_flags): + return " " + " ".join([config.clang] + compile_flags) + " " + +# Add substitutions. +config.substitutions.append(("%clang ", build_invocation(c_flags))) +config.substitutions.append(("%clang_scudo ", build_invocation(c_flags + scudo_flags))) +config.substitutions.append(("%clangxx_scudo ", build_invocation(cxx_flags + scudo_flags))) +config.substitutions.append(("%shared_libscudo", shared_libscudo)) + +# Disable GWP-ASan for scudo internal tests. +default_scudo_opts = '' +if config.gwp_asan: + default_scudo_opts += 'GWP_ASAN_Enabled=false:' + +config.substitutions.append(('%env_scudo_opts=', + 'env SCUDO_OPTIONS=' + default_scudo_opts)) + +# Hardened Allocator tests are currently supported on Linux only. +if config.host_os not in ['Linux']: + config.unsupported = True diff --git a/compiler-rt/test/scudo/standalone/lit.site.cfg.py.in b/compiler-rt/test/scudo/standalone/lit.site.cfg.py.in new file mode 100644 --- /dev/null +++ b/compiler-rt/test/scudo/standalone/lit.site.cfg.py.in @@ -0,0 +1,12 @@ +@LIT_SITE_CFG_IN_HEADER@ + +config.name_suffix = "@SCUDO_STANDALONE_TEST_CONFIG_SUFFIX@" +config.target_arch = "@SCUDO_STANDALONE_TEST_TARGET_ARCH@" +config.target_cflags = "@SCUDO_STANDALONE_TEST_TARGET_CFLAGS@" +config.test_suite_supports_overriding_runtime_lib_path = True + +# Load common config for all compiler-rt lit tests. +lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured") + +# Load tool-specific config that would do the real work. +lit_config.load_config(config, "@SCUDO_STANDALONE_LIT_SOURCE_DIR@/lit.cfg.py") diff --git a/compiler-rt/test/scudo/malloc.cpp b/compiler-rt/test/scudo/standalone/malloc.cpp rename from compiler-rt/test/scudo/malloc.cpp rename to compiler-rt/test/scudo/standalone/malloc.cpp diff --git a/compiler-rt/test/scudo/memalign.c b/compiler-rt/test/scudo/standalone/memalign.c rename from compiler-rt/test/scudo/memalign.c rename to compiler-rt/test/scudo/standalone/memalign.c --- a/compiler-rt/test/scudo/memalign.c +++ b/compiler-rt/test/scudo/standalone/memalign.c @@ -1,10 +1,10 @@ // RUN: %clang_scudo %s -o %t -// RUN: %run %t valid 2>&1 -// RUN: not %run %t invalid 2>&1 | FileCheck --check-prefix=CHECK-align %s -// RUN: %env_scudo_opts=allocator_may_return_null=1 %run %t invalid 2>&1 -// RUN: not %run %t double-free 2>&1 | FileCheck --check-prefix=CHECK-double-free %s -// RUN: %env_scudo_opts=DeallocationTypeMismatch=1 not %run %t realloc 2>&1 | FileCheck --check-prefix=CHECK-realloc %s -// RUN: %env_scudo_opts=DeallocationTypeMismatch=0 %run %t realloc 2>&1 +// RUN: %run %t valid 2>&1 +// RUN: %env_scudo_opts=may_return_null=0 not --crash %run %t invalid 2>&1 | FileCheck --check-prefix=CHECK-align %s +// RUN: %env_scudo_opts=may_return_null=1 %run %t invalid 2>&1 +// RUN: not --crash %run %t double-free 2>&1 | FileCheck --check-prefix=CHECK-double-free %s +// RUN: %env_scudo_opts=dealloc_type_mismatch=1 not --crash %run %t realloc 2>&1 | FileCheck --check-prefix=CHECK-realloc %s +// RUN: %env_scudo_opts=dealloc_type_mismatch=0 %run %t realloc 2>&1 // Tests that the various aligned allocation functions work as intended. Also // tests for the condition where the alignment is not a power of 2. diff --git a/compiler-rt/test/scudo/mismatch.cpp b/compiler-rt/test/scudo/standalone/mismatch.cpp rename from compiler-rt/test/scudo/mismatch.cpp rename to compiler-rt/test/scudo/standalone/mismatch.cpp --- a/compiler-rt/test/scudo/mismatch.cpp +++ b/compiler-rt/test/scudo/standalone/mismatch.cpp @@ -1,8 +1,8 @@ // RUN: %clangxx_scudo %s -o %t -// RUN: %env_scudo_opts=DeallocationTypeMismatch=1 not %run %t mallocdel 2>&1 | FileCheck --check-prefix=CHECK-dealloc %s -// RUN: %env_scudo_opts=DeallocationTypeMismatch=0 %run %t mallocdel 2>&1 -// RUN: %env_scudo_opts=DeallocationTypeMismatch=1 not %run %t newfree 2>&1 | FileCheck --check-prefix=CHECK-dealloc %s -// RUN: %env_scudo_opts=DeallocationTypeMismatch=0 %run %t newfree 2>&1 +// RUN: %env_scudo_opts=dealloc_type_mismatch=1 not --crash %run %t mallocdel 2>&1 | FileCheck --check-prefix=CHECK-dealloc %s +// RUN: %env_scudo_opts=dealloc_type_mismatch=0 %run %t mallocdel 2>&1 +// RUN: %env_scudo_opts=dealloc_type_mismatch=1 not --crash %run %t newfree 2>&1 | FileCheck --check-prefix=CHECK-dealloc %s +// RUN: %env_scudo_opts=dealloc_type_mismatch=0 %run %t newfree 2>&1 // Tests that type mismatches between allocation and deallocation functions are // caught when the related option is set. diff --git a/compiler-rt/test/scudo/options.cpp b/compiler-rt/test/scudo/standalone/options.cpp rename from compiler-rt/test/scudo/options.cpp rename to compiler-rt/test/scudo/standalone/options.cpp --- a/compiler-rt/test/scudo/options.cpp +++ b/compiler-rt/test/scudo/standalone/options.cpp @@ -1,7 +1,7 @@ // RUN: %clangxx_scudo %s -o %t -// RUN: %run %t 2>&1 -// RUN: %env_scudo_opts=DeallocationTypeMismatch=0 %run %t 2>&1 -// RUN: %env_scudo_opts=DeallocationTypeMismatch=1 not %run %t 2>&1 | FileCheck %s +// RUN: not --crash %run %t 2>&1 | FileCheck %s +// RUN: %env_scudo_opts=dealloc_type_mismatch=0 %run %t 2>&1 +// RUN: %env_scudo_opts=dealloc_type_mismatch=1 not --crash %run %t 2>&1 | FileCheck %s // Tests that the options can be passed using getScudoDefaultOptions, and that // the environment ones take precedence over them. @@ -11,7 +11,7 @@ #include extern "C" const char *__scudo_default_options() { - return "DeallocationTypeMismatch=0"; // Defaults to true in scudo_flags.inc. + return "dealloc_type_mismatch=1"; // Defaults to false in flags.inc. } int main(int argc, char **argv) { diff --git a/compiler-rt/test/scudo/preinit.c b/compiler-rt/test/scudo/standalone/preinit.c rename from compiler-rt/test/scudo/preinit.c rename to compiler-rt/test/scudo/standalone/preinit.c diff --git a/compiler-rt/test/scudo/preload.cpp b/compiler-rt/test/scudo/standalone/preload.cpp rename from compiler-rt/test/scudo/preload.cpp rename to compiler-rt/test/scudo/standalone/preload.cpp --- a/compiler-rt/test/scudo/preload.cpp +++ b/compiler-rt/test/scudo/standalone/preload.cpp @@ -1,8 +1,7 @@ // Test that the preloaded runtime works without linking the static library. // RUN: %clang %s -lstdc++ -o %t -// RUN: env LD_PRELOAD=%shared_libscudo not %run %t 2>&1 | FileCheck %s -// RUN: env LD_PRELOAD=%shared_minlibscudo not %run %t 2>&1 | FileCheck %s +// RUN: env LD_PRELOAD=%shared_libscudo not --crash %run %t 2>&1 | FileCheck %s // This way of setting LD_PRELOAD does not work with Android test runner. // REQUIRES: !android diff --git a/compiler-rt/test/scudo/random_shuffle.cpp b/compiler-rt/test/scudo/standalone/random_shuffle.cpp rename from compiler-rt/test/scudo/random_shuffle.cpp rename to compiler-rt/test/scudo/standalone/random_shuffle.cpp diff --git a/compiler-rt/test/scudo/sized-delete.cpp b/compiler-rt/test/scudo/standalone/sized-delete.cpp rename from compiler-rt/test/scudo/sized-delete.cpp rename to compiler-rt/test/scudo/standalone/sized-delete.cpp --- a/compiler-rt/test/scudo/sized-delete.cpp +++ b/compiler-rt/test/scudo/standalone/sized-delete.cpp @@ -1,10 +1,10 @@ // RUN: %clangxx_scudo -fsized-deallocation %s -o %t -// RUN: %env_scudo_opts=DeleteSizeMismatch=1 %run %t gooddel 2>&1 -// RUN: %env_scudo_opts=DeleteSizeMismatch=1 not %run %t baddel 2>&1 | FileCheck %s -// RUN: %env_scudo_opts=DeleteSizeMismatch=0 %run %t baddel 2>&1 -// RUN: %env_scudo_opts=DeleteSizeMismatch=1 %run %t gooddelarr 2>&1 -// RUN: %env_scudo_opts=DeleteSizeMismatch=1 not %run %t baddelarr 2>&1 | FileCheck %s -// RUN: %env_scudo_opts=DeleteSizeMismatch=0 %run %t baddelarr 2>&1 +// RUN: %env_scudo_opts=delete_size_mismatch=1 %run %t gooddel 2>&1 +// RUN: %env_scudo_opts=delete_size_mismatch=1 not --crash %run %t baddel 2>&1 | FileCheck %s +// RUN: %env_scudo_opts=delete_size_mismatch=0 %run %t baddel 2>&1 +// RUN: %env_scudo_opts=delete_size_mismatch=1 %run %t gooddelarr 2>&1 +// RUN: %env_scudo_opts=delete_size_mismatch=1 not --crash %run %t baddelarr 2>&1 | FileCheck %s +// RUN: %env_scudo_opts=delete_size_mismatch=0 %run %t baddelarr 2>&1 // Ensures that the sized delete operator errors out when the appropriate // option is passed and the sizes do not match between allocation and diff --git a/compiler-rt/test/scudo/stats.c b/compiler-rt/test/scudo/standalone/stats.c rename from compiler-rt/test/scudo/stats.c rename to compiler-rt/test/scudo/standalone/stats.c --- a/compiler-rt/test/scudo/stats.c +++ b/compiler-rt/test/scudo/standalone/stats.c @@ -9,7 +9,7 @@ #include -#include +void __scudo_print_stats(); int main(int argc, char **argv) { free(malloc(1U)); diff --git a/compiler-rt/test/scudo/tsd_destruction.c b/compiler-rt/test/scudo/standalone/tsd_destruction.c rename from compiler-rt/test/scudo/tsd_destruction.c rename to compiler-rt/test/scudo/standalone/tsd_destruction.c diff --git a/compiler-rt/test/scudo/symbols.test b/compiler-rt/test/scudo/symbols.test deleted file mode 100644 --- a/compiler-rt/test/scudo/symbols.test +++ /dev/null @@ -1,8 +0,0 @@ -UNSUPPORTED: android - -Verify that various functions are *not* present in the minimal binary. Presence -of those symbols in the minimal runtime would mean that the split code made it -back into the core Sanitizer runtime library. - -RUN: nm %shared_minlibscudo | not grep Symbolizer -RUN: nm %shared_minlibscudo | not grep Coverage