diff options
Diffstat (limited to 'compiler-rt')
52 files changed, 402 insertions, 154 deletions
diff --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp index 9ebe4d08ec8c..752ba9ab32c7 100644 --- a/compiler-rt/lib/asan/asan_allocator.cpp +++ b/compiler-rt/lib/asan/asan_allocator.cpp @@ -547,6 +547,7 @@ struct Allocator { ComputeUserRequestedAlignmentLog(alignment); if (alignment < min_alignment) alignment = min_alignment; + bool upgraded_from_zero = false; if (size == 0) { // We'd be happy to avoid allocating memory for zero-size requests, but // some programs/tests depend on this behavior and assume that malloc @@ -555,6 +556,7 @@ struct Allocator { // consecutive "new" calls must be different even if the allocated size // is zero. size = 1; + upgraded_from_zero = true; } CHECK(IsPowerOfTwo(alignment)); uptr rz_log = ComputeRZLog(size); @@ -637,6 +639,10 @@ struct Allocator { *shadow = fl.poison_partial ? (size & (ASAN_SHADOW_GRANULARITY - 1)) : 0; } + if (upgraded_from_zero) + PoisonShadow(user_beg, ASAN_SHADOW_GRANULARITY, + kAsanHeapLeftRedzoneMagic); + AsanStats &thread_stats = GetCurrentThreadStats(); thread_stats.mallocs++; thread_stats.malloced += size; diff --git a/compiler-rt/lib/asan/asan_errors.h b/compiler-rt/lib/asan/asan_errors.h index b3af655e6663..f339b35d2a76 100644 --- a/compiler-rt/lib/asan/asan_errors.h +++ b/compiler-rt/lib/asan/asan_errors.h @@ -362,7 +362,7 @@ struct ErrorBadParamsToCopyContiguousContainerAnnotations : ErrorBase { u32 tid, BufferedStackTrace *stack_, uptr old_storage_beg_, uptr old_storage_end_, uptr new_storage_beg_, uptr new_storage_end_) : ErrorBase(tid, 10, - "bad-__sanitizer_annotate_double_ended_contiguous_container"), + "bad-__sanitizer_copy_contiguous_container_annotations"), stack(stack_), old_storage_beg(old_storage_beg_), old_storage_end(old_storage_end_), diff --git a/compiler-rt/lib/asan/asan_malloc_win.cpp b/compiler-rt/lib/asan/asan_malloc_win.cpp index 8d98da940800..ea6f7dfaa08c 100644 --- a/compiler-rt/lib/asan/asan_malloc_win.cpp +++ b/compiler-rt/lib/asan/asan_malloc_win.cpp @@ -322,6 +322,22 @@ void *SharedReAlloc(ReAllocFunction reallocFunc, SizeFunction heapSizeFunc, } } + if (dwFlags & HEAP_REALLOC_IN_PLACE_ONLY) { + size_t old_usable_size = asan_malloc_usable_size(lpMem, pc, bp); + if (dwBytes == old_usable_size) { + // Nothing to change, return the current pointer. + return lpMem; + } else if (dwBytes >= old_usable_size) { + // Growing with HEAP_REALLOC_IN_PLACE_ONLY is not supported. + return nullptr; + } else { + // Shrinking with HEAP_REALLOC_IN_PLACE_ONLY is not yet supported. + // For now return the current pointer and + // leave the allocation size as it is. + return lpMem; + } + } + if (ownershipState == ASAN && !only_asan_supported_flags) { // Conversion to unsupported flags allocation, // transfer this allocation back to the original allocator. diff --git a/compiler-rt/lib/asan/tests/asan_test.cpp b/compiler-rt/lib/asan/tests/asan_test.cpp index 2d054ee859ed..2d23a12cc6ae 100644 --- a/compiler-rt/lib/asan/tests/asan_test.cpp +++ b/compiler-rt/lib/asan/tests/asan_test.cpp @@ -395,7 +395,8 @@ TEST(AddressSanitizer, ReallocTest) { } free(ptr); // Realloc pointer returned by malloc(0). - int *ptr2 = Ident((int*)malloc(0)); + void *ptr0 = malloc(0); + int *ptr2 = Ident((int *)ptr0); ptr2 = Ident((int*)realloc(ptr2, sizeof(*ptr2))); *ptr2 = 42; EXPECT_EQ(42, *ptr2); diff --git a/compiler-rt/lib/builtins/assembly.h b/compiler-rt/lib/builtins/assembly.h index d7db7d818945..d1e532813aa2 100644 --- a/compiler-rt/lib/builtins/assembly.h +++ b/compiler-rt/lib/builtins/assembly.h @@ -304,7 +304,7 @@ .globl FUNC_SYMBOL(SYMBOL_NAME(name)) SEPARATOR \ SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \ - .set FUNC_SYMBOL(SYMBOL_NAME(name)), FUNC_SYMBOL(target) SEPARATOR + .set FUNC_SYMBOL(SYMBOL_NAME(name)), FUNC_SYMBOL(SYMBOL_NAME(target)) SEPARATOR #if defined(__ARM_EABI__) #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \ diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64.c b/compiler-rt/lib/builtins/cpu_model/aarch64.c index be002dd71992..d7880529ebe7 100644 --- a/compiler-rt/lib/builtins/cpu_model/aarch64.c +++ b/compiler-rt/lib/builtins/cpu_model/aarch64.c @@ -34,12 +34,12 @@ typedef struct __ifunc_arg_t { _Bool __aarch64_have_lse_atomics __attribute__((visibility("hidden"), nocommon)) = false; -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) // clang-format off: should not reorder sys/auxv.h alphabetically #include <sys/auxv.h> // clang-format on #include "aarch64/hwcap.inc" -#include "aarch64/lse_atomics/freebsd.inc" +#include "aarch64/lse_atomics/elf_aux_info.inc" #elif defined(__Fuchsia__) #include "aarch64/hwcap.inc" #include "aarch64/lse_atomics/fuchsia.inc" @@ -68,9 +68,9 @@ struct { // clang-format off #if defined(__APPLE__) #include "aarch64/fmv/apple.inc" -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__OpenBSD__) #include "aarch64/fmv/mrs.inc" -#include "aarch64/fmv/freebsd.inc" +#include "aarch64/fmv/elf_aux_info.inc" #elif defined(__Fuchsia__) #include "aarch64/fmv/fuchsia.inc" #elif defined(__ANDROID__) diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/freebsd.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/elf_aux_info.inc index aa975dc854f9..aa975dc854f9 100644 --- a/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/freebsd.inc +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/elf_aux_info.inc diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/freebsd.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/elf_aux_info.inc index 4a1f9c2c27c8..4a1f9c2c27c8 100644 --- a/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/freebsd.inc +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/lse_atomics/elf_aux_info.inc diff --git a/compiler-rt/lib/builtins/crtbegin.c b/compiler-rt/lib/builtins/crtbegin.c index 447474bd0b69..8b5f98fdd04e 100644 --- a/compiler-rt/lib/builtins/crtbegin.c +++ b/compiler-rt/lib/builtins/crtbegin.c @@ -19,7 +19,7 @@ __attribute__((visibility("hidden"))) void *__dso_handle = &__dso_handle; #ifdef EH_USE_FRAME_REGISTRY -__extension__ static void *__EH_FRAME_LIST__[] +__extension__ static void *const __EH_FRAME_LIST__[] __attribute__((section(".eh_frame"), aligned(sizeof(void *)))) = {}; extern void __register_frame_info(const void *, void *) __attribute__((weak)); diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp index ad3a65aff80e..af9c260537e2 100644 --- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp @@ -306,6 +306,11 @@ static int RunInMultipleProcesses(const std::vector<std::string> &Args, return HasErrors ? 1 : 0; } +void StartRssThread(Fuzzer *F, size_t RssLimitMb); + +// Fuchsia needs to do some book checking before starting the RssThread, +// so it has its own implementation. +#if !LIBFUZZER_FUCHSIA static void RssThread(Fuzzer *F, size_t RssLimitMb) { while (true) { SleepSeconds(1); @@ -315,12 +320,13 @@ static void RssThread(Fuzzer *F, size_t RssLimitMb) { } } -static void StartRssThread(Fuzzer *F, size_t RssLimitMb) { +void StartRssThread(Fuzzer *F, size_t RssLimitMb) { if (!RssLimitMb) return; std::thread T(RssThread, F, RssLimitMb); T.detach(); } +#endif int RunOneTest(Fuzzer *F, const char *InputFilePath, size_t MaxLen) { Unit U = FileToVector(InputFilePath); diff --git a/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp b/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp index 7f065c79e717..1ae8e6635053 100644 --- a/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp @@ -68,6 +68,9 @@ void ExitOnErr(zx_status_t Status, const char *Syscall) { } void AlarmHandler(int Seconds) { + // Signal the alarm thread started. + ExitOnErr(_zx_object_signal(SignalHandlerEvent, 0, ZX_USER_SIGNAL_0), + "_zx_object_signal alarm"); while (true) { SleepSeconds(Seconds); Fuzzer::StaticAlarmCallback(); @@ -282,6 +285,7 @@ void CrashHandler() { Self, ZX_EXCEPTION_CHANNEL_DEBUGGER, &Channel.Handle), "_zx_task_create_exception_channel"); + // Signal the crash thread started. ExitOnErr(_zx_object_signal(SignalHandlerEvent, 0, ZX_USER_SIGNAL_0), "_zx_object_signal"); @@ -385,10 +389,49 @@ void StopSignalHandler() { _zx_handle_close(SignalHandlerEvent); } +void RssThread(Fuzzer *F, size_t RssLimitMb) { + // Signal the rss thread started. + // + // We must wait for this thread to start because we could accidentally suspend + // it while the crash handler is attempting to handle the + // ZX_EXCP_THREAD_STARTING exception. If the crash handler is suspended by the + // lsan machinery, then there's no way for this thread to indicate it's + // suspended because it's blocked on waiting for the exception to be handled. + ExitOnErr(_zx_object_signal(SignalHandlerEvent, 0, ZX_USER_SIGNAL_0), + "_zx_object_signal rss"); + while (true) { + SleepSeconds(1); + size_t Peak = GetPeakRSSMb(); + if (Peak > RssLimitMb) + F->RssLimitCallback(); + } +} + } // namespace +void StartRssThread(Fuzzer *F, size_t RssLimitMb) { + // Set up the crash handler and wait until it is ready before proceeding. + assert(SignalHandlerEvent == ZX_HANDLE_INVALID); + ExitOnErr(_zx_event_create(0, &SignalHandlerEvent), "_zx_event_create"); + + if (!RssLimitMb) + return; + std::thread T(RssThread, F, RssLimitMb); + T.detach(); + + // Wait for the rss thread to start. + ExitOnErr(_zx_object_wait_one(SignalHandlerEvent, ZX_USER_SIGNAL_0, + ZX_TIME_INFINITE, nullptr), + "_zx_object_wait_one rss"); + ExitOnErr(_zx_object_signal(SignalHandlerEvent, ZX_USER_SIGNAL_0, 0), + "_zx_object_signal rss clear"); +} + // Platform specific functions. void SetSignalHandler(const FuzzingOptions &Options) { + assert(SignalHandlerEvent != ZX_HANDLE_INVALID && + "This should've been setup by StartRssThread."); + // Make sure information from libFuzzer and the sanitizers are easy to // reassemble. `__sanitizer_log_write` has the added benefit of ensuring the // DSO map is always available for the symbolizer. @@ -404,6 +447,20 @@ void SetSignalHandler(const FuzzingOptions &Options) { if (Options.HandleAlrm && Options.UnitTimeoutSec > 0) { std::thread T(AlarmHandler, Options.UnitTimeoutSec / 2 + 1); T.detach(); + + // Wait for the alarm thread to start. + // + // We must wait for this thread to start because we could accidentally + // suspend it while the crash handler is attempting to handle the + // ZX_EXCP_THREAD_STARTING exception. If the crash handler is suspended by + // the lsan machinery, then there's no way for this thread to indicate it's + // suspended because it's blocked on waiting for the exception to be + // handled. + ExitOnErr(_zx_object_wait_one(SignalHandlerEvent, ZX_USER_SIGNAL_0, + ZX_TIME_INFINITE, nullptr), + "_zx_object_wait_one alarm"); + ExitOnErr(_zx_object_signal(SignalHandlerEvent, ZX_USER_SIGNAL_0, 0), + "_zx_object_signal alarm clear"); } // Options.HandleInt and Options.HandleTerm are not supported on Fuchsia @@ -413,9 +470,6 @@ void SetSignalHandler(const FuzzingOptions &Options) { !Options.HandleFpe && !Options.HandleAbrt && !Options.HandleTrap) return; - // Set up the crash handler and wait until it is ready before proceeding. - ExitOnErr(_zx_event_create(0, &SignalHandlerEvent), "_zx_event_create"); - SignalHandler = std::thread(CrashHandler); zx_status_t Status = _zx_object_wait_one(SignalHandlerEvent, ZX_USER_SIGNAL_0, ZX_TIME_INFINITE, nullptr); diff --git a/compiler-rt/lib/gwp_asan/tests/basic.cpp b/compiler-rt/lib/gwp_asan/tests/basic.cpp index 7d36a2ee1f94..ec2cacc00616 100644 --- a/compiler-rt/lib/gwp_asan/tests/basic.cpp +++ b/compiler-rt/lib/gwp_asan/tests/basic.cpp @@ -8,6 +8,8 @@ #include "gwp_asan/tests/harness.h" +#include <unistd.h> + TEST_F(CustomGuardedPoolAllocator, BasicAllocation) { InitNumSlots(1); void *Ptr = GPA.allocate(1); diff --git a/compiler-rt/lib/gwp_asan/tests/compression.cpp b/compiler-rt/lib/gwp_asan/tests/compression.cpp index 2423c866a531..91b09770836a 100644 --- a/compiler-rt/lib/gwp_asan/tests/compression.cpp +++ b/compiler-rt/lib/gwp_asan/tests/compression.cpp @@ -11,6 +11,7 @@ namespace gwp_asan { namespace compression { +namespace { TEST(GwpAsanCompressionTest, SingleByteVarInt) { uint8_t Compressed[1]; @@ -263,5 +264,7 @@ TEST(GwpAsanCompressionTest, CompressPartiallySucceedsWithTooSmallBuffer) { EXPECT_EQ(pack(Uncompressed, 3u, Compressed, 6u), 5u); EXPECT_EQ(pack(Uncompressed, 3u, Compressed, 3 * kBytesForLargestVarInt), 5u); } + +} // namespace } // namespace compression } // namespace gwp_asan diff --git a/compiler-rt/lib/gwp_asan/tests/never_allocated.cpp b/compiler-rt/lib/gwp_asan/tests/never_allocated.cpp index 37a4b384e4ac..6e1ee47d86a5 100644 --- a/compiler-rt/lib/gwp_asan/tests/never_allocated.cpp +++ b/compiler-rt/lib/gwp_asan/tests/never_allocated.cpp @@ -12,6 +12,8 @@ #include "gwp_asan/crash_handler.h" #include "gwp_asan/tests/harness.h" +#include <unistd.h> + TEST_P(BacktraceGuardedPoolAllocatorDeathTest, NeverAllocated) { size_t PageSize = sysconf(_SC_PAGESIZE); diff --git a/compiler-rt/lib/gwp_asan/tests/slot_reuse.cpp b/compiler-rt/lib/gwp_asan/tests/slot_reuse.cpp index f2a77b094a89..010d29a23382 100644 --- a/compiler-rt/lib/gwp_asan/tests/slot_reuse.cpp +++ b/compiler-rt/lib/gwp_asan/tests/slot_reuse.cpp @@ -6,9 +6,11 @@ // //===----------------------------------------------------------------------===// +#include <set> + #include "gwp_asan/tests/harness.h" -#include <set> +namespace { void singleByteGoodAllocDealloc(gwp_asan::GuardedPoolAllocator *GPA) { void *Ptr = GPA->allocate(1); @@ -72,3 +74,5 @@ TEST_F(CustomGuardedPoolAllocator, NoReuseBeforeNecessary129) { InitNumSlots(kPoolSize); runNoReuseBeforeNecessary(&GPA, kPoolSize); } + +} // namespace diff --git a/compiler-rt/lib/gwp_asan/tests/thread_contention.cpp b/compiler-rt/lib/gwp_asan/tests/thread_contention.cpp index 26ccd8e60506..311d0c0666b3 100644 --- a/compiler-rt/lib/gwp_asan/tests/thread_contention.cpp +++ b/compiler-rt/lib/gwp_asan/tests/thread_contention.cpp @@ -15,6 +15,8 @@ #include <thread> #include <vector> +namespace { + void asyncTask(gwp_asan::GuardedPoolAllocator *GPA, std::atomic<bool> *StartingGun, unsigned NumIterations) { while (!*StartingGun) { @@ -63,3 +65,5 @@ TEST_F(CustomGuardedPoolAllocator, ThreadContention) { InitNumSlots(NumThreads); runThreadContentionTest(NumThreads, NumIterations, &GPA); } + +} // namespace diff --git a/compiler-rt/lib/msan/msan_allocator.cpp b/compiler-rt/lib/msan/msan_allocator.cpp index 2b543db49d36..64df863839c0 100644 --- a/compiler-rt/lib/msan/msan_allocator.cpp +++ b/compiler-rt/lib/msan/msan_allocator.cpp @@ -230,6 +230,12 @@ static void *MsanAllocate(BufferedStackTrace *stack, uptr size, uptr alignment, __msan_set_origin(allocated, size, o.raw_id()); } } + + uptr actually_allocated_size = allocator.GetActuallyAllocatedSize(allocated); + // For compatibility, the allocator converted 0-sized allocations into 1 byte + if (size == 0 && actually_allocated_size > 0 && flags()->poison_in_malloc) + __msan_poison(allocated, 1); + UnpoisonParam(2); RunMallocHooks(allocated, size); return allocated; diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp index d89cec88cc43..1b1ff9b21173 100644 --- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp @@ -47,41 +47,12 @@ using namespace __sanitizer; -DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, usize size) -DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr) - namespace { struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> { static bool UseImpl() { return !__rtsan_is_initialized(); } }; } // namespace -// See note in tsan as to why this is necessary -static pthread_cond_t *init_cond(pthread_cond_t *c, bool force = false) { - if (!common_flags()->legacy_pthread_cond) - return c; - - atomic_uintptr_t *p = (atomic_uintptr_t *)c; - uptr cond = atomic_load(p, memory_order_acquire); - if (!force && cond != 0) - return (pthread_cond_t *)cond; - void *newcond = WRAP(malloc)(sizeof(pthread_cond_t)); - internal_memset(newcond, 0, sizeof(pthread_cond_t)); - if (atomic_compare_exchange_strong(p, &cond, (uptr)newcond, - memory_order_acq_rel)) - return (pthread_cond_t *)newcond; - WRAP(free)(newcond); - return (pthread_cond_t *)cond; -} - -static void destroy_cond(pthread_cond_t *cond) { - if (common_flags()->legacy_pthread_cond) { - // Free our aux cond and zero the pointer to not leave dangling pointers. - WRAP(free)(cond); - atomic_store((atomic_uintptr_t *)cond, 0, memory_order_relaxed); - } -} - // Filesystem INTERCEPTOR(int, open, const char *path, int oflag, ...) { @@ -799,42 +770,34 @@ INTERCEPTOR(int, pthread_join, pthread_t thread, void **value_ptr) { INTERCEPTOR(int, pthread_cond_init, pthread_cond_t *cond, const pthread_condattr_t *a) { __rtsan_notify_intercepted_call("pthread_cond_init"); - pthread_cond_t *c = init_cond(cond, true); - return REAL(pthread_cond_init)(c, a); + return REAL(pthread_cond_init)(cond, a); } INTERCEPTOR(int, pthread_cond_signal, pthread_cond_t *cond) { __rtsan_notify_intercepted_call("pthread_cond_signal"); - pthread_cond_t *c = init_cond(cond); - return REAL(pthread_cond_signal)(c); + return REAL(pthread_cond_signal)(cond); } INTERCEPTOR(int, pthread_cond_broadcast, pthread_cond_t *cond) { __rtsan_notify_intercepted_call("pthread_cond_broadcast"); - pthread_cond_t *c = init_cond(cond); - return REAL(pthread_cond_broadcast)(c); + return REAL(pthread_cond_broadcast)(cond); } INTERCEPTOR(int, pthread_cond_wait, pthread_cond_t *cond, pthread_mutex_t *mutex) { __rtsan_notify_intercepted_call("pthread_cond_wait"); - pthread_cond_t *c = init_cond(cond); - return REAL(pthread_cond_wait)(c, mutex); + return REAL(pthread_cond_wait)(cond, mutex); } INTERCEPTOR(int, pthread_cond_timedwait, pthread_cond_t *cond, pthread_mutex_t *mutex, const timespec *ts) { __rtsan_notify_intercepted_call("pthread_cond_timedwait"); - pthread_cond_t *c = init_cond(cond); - return REAL(pthread_cond_timedwait)(c, mutex, ts); + return REAL(pthread_cond_timedwait)(cond, mutex, ts); } INTERCEPTOR(int, pthread_cond_destroy, pthread_cond_t *cond) { __rtsan_notify_intercepted_call("pthread_cond_destroy"); - pthread_cond_t *c = init_cond(cond); - int res = REAL(pthread_cond_destroy)(c); - destroy_cond(c); - return res; + return REAL(pthread_cond_destroy)(cond); } INTERCEPTOR(int, pthread_rwlock_rdlock, pthread_rwlock_t *lock) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 2d6cf7fc3282..a96d325d0898 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -1285,8 +1285,34 @@ INTERCEPTOR(int, puts, char *s) { #endif #if SANITIZER_INTERCEPT_PRCTL -INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3, - unsigned long arg4, unsigned long arg5) { + +# if defined(__aarch64__) +// https://llvm.org/docs/PointerAuth.html +// AArch64 is currently the only architecture with full PAC support. +// Avoid adding PAC instructions to prevent crashes caused by +// prctl(PR_PAC_RESET_KEYS, ...). Since PR_PAC_RESET_KEYS resets the +// authentication key, using the old key afterward will lead to a crash. + +# if defined(__ARM_FEATURE_BTI_DEFAULT) +# define BRANCH_PROTECTION_ATTRIBUTE \ + __attribute__((target("branch-protection=bti"))) +# else +# define BRANCH_PROTECTION_ATTRIBUTE \ + __attribute__((target("branch-protection=none"))) +# endif + +# define PRCTL_INTERCEPTOR(ret_type, func, ...) \ + DEFINE_REAL(ret_type, func, __VA_ARGS__) \ + DECLARE_WRAPPER(ret_type, func, __VA_ARGS__) \ + extern "C" INTERCEPTOR_ATTRIBUTE BRANCH_PROTECTION_ATTRIBUTE ret_type \ + WRAP(func)(__VA_ARGS__) + +# else +# define PRCTL_INTERCEPTOR INTERCEPTOR +# endif + +PRCTL_INTERCEPTOR(int, prctl, int option, unsigned long arg2, + unsigned long arg3, unsigned long arg4, unsigned long arg5) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); static const int PR_SET_NAME = 15; @@ -1326,7 +1352,7 @@ INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3, } return res; } -#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl) +# define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl) #else #define INIT_PRCTL #endif // SANITIZER_INTERCEPT_PRCTL diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc index 521fc116f288..ee3ac723e366 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_syscalls.inc @@ -143,6 +143,12 @@ struct sanitizer_kernel_sockaddr { char sa_data[14]; }; +struct sanitizer_kernel_open_how { + u64 flags; + u64 mode; + u64 resolve; +}; + // Real sigset size is always passed as a syscall argument. // Declare it "void" to catch sizeof(kernel_sigset_t). typedef void kernel_sigset_t; @@ -2843,6 +2849,18 @@ PRE_SYSCALL(openat)(long dfd, const void *filename, long flags, long mode) { POST_SYSCALL(openat) (long res, long dfd, const void *filename, long flags, long mode) {} +PRE_SYSCALL(openat2)(long dfd, const void* filename, + const sanitizer_kernel_open_how* how, uptr howlen) { + if (filename) + PRE_READ(filename, __sanitizer::internal_strlen((const char*)filename) + 1); + + if (how) + PRE_READ(how, howlen); +} + +POST_SYSCALL(openat2)(long res, long dfd, const void* filename, + const sanitizer_kernel_open_how* how, uptr howlen) {} + PRE_SYSCALL(newfstatat) (long dfd, const void *filename, void *statbuf, long flag) { if (filename) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index f5cb85bc1bf3..530ff90c4cd1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -29,6 +29,7 @@ # include "sanitizer_solaris.h" # if SANITIZER_HAIKU +# define _GNU_SOURCE # define _DEFAULT_SOURCE # endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp index 4c1e00528923..c4fa1e3c1f6f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp @@ -71,14 +71,8 @@ #include <semaphore.h> #include <signal.h> #include <stddef.h> -#include <md5.h> -#include <sha224.h> -#include <sha256.h> -#include <sha384.h> -#include <sha512.h> #include <stdio.h> #include <stringlist.h> -#include <term.h> #include <termios.h> #include <time.h> #include <ttyent.h> @@ -370,22 +364,6 @@ const int si_SEGV_MAPERR = SEGV_MAPERR; const int si_SEGV_ACCERR = SEGV_ACCERR; const int unvis_valid = UNVIS_VALID; const int unvis_validpush = UNVIS_VALIDPUSH; - -const unsigned MD5_CTX_sz = sizeof(MD5_CTX); -const unsigned MD5_return_length = MD5_DIGEST_STRING_LENGTH; - -#define SHA2_CONST(LEN) \ - const unsigned SHA##LEN##_CTX_sz = sizeof(SHA##LEN##_CTX); \ - const unsigned SHA##LEN##_return_length = SHA##LEN##_DIGEST_STRING_LENGTH; \ - const unsigned SHA##LEN##_block_length = SHA##LEN##_BLOCK_LENGTH; \ - const unsigned SHA##LEN##_digest_length = SHA##LEN##_DIGEST_LENGTH - -SHA2_CONST(224); -SHA2_CONST(256); -SHA2_CONST(384); -SHA2_CONST(512); - -#undef SHA2_CONST } // namespace __sanitizer using namespace __sanitizer; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h index 382b67ce78eb..1cbb40e0b2ff 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h @@ -710,22 +710,6 @@ extern unsigned IOCTL_KDSKBMODE; extern const int si_SEGV_MAPERR; extern const int si_SEGV_ACCERR; -extern const unsigned MD5_CTX_sz; -extern const unsigned MD5_return_length; - -#define SHA2_EXTERN(LEN) \ - extern const unsigned SHA##LEN##_CTX_sz; \ - extern const unsigned SHA##LEN##_return_length; \ - extern const unsigned SHA##LEN##_block_length; \ - extern const unsigned SHA##LEN##_digest_length - -SHA2_EXTERN(224); -SHA2_EXTERN(256); -SHA2_EXTERN(384); -SHA2_EXTERN(512); - -#undef SHA2_EXTERN - struct __sanitizer_cap_rights { u64 cr_rights[2]; }; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp index aacd28c55cea..435f3b2861dc 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp @@ -498,7 +498,6 @@ struct urio_command { #include <md5.h> #include <rmd160.h> #include <soundcard.h> -#include <term.h> #include <termios.h> #include <time.h> #include <ttyent.h> @@ -515,7 +514,7 @@ struct urio_command { #include <stringlist.h> #if defined(__x86_64__) -#include <nvmm.h> +#include <dev/nvmm/nvmm_ioctl.h> #endif // clang-format on diff --git a/compiler-rt/lib/scudo/standalone/common.cpp b/compiler-rt/lib/scudo/standalone/common.cpp index 80134c39e757..f7c1b420f4c7 100644 --- a/compiler-rt/lib/scudo/standalone/common.cpp +++ b/compiler-rt/lib/scudo/standalone/common.cpp @@ -16,9 +16,6 @@ namespace scudo { uptr PageSizeCached = 0; uptr PageSizeLogCached = 0; -// Must be defined in platform specific code. -uptr getPageSize(); - // This must be called in the init path or there could be a race if multiple // threads try to set the cached values. uptr getPageSizeSlow() { diff --git a/compiler-rt/lib/scudo/standalone/common.h b/compiler-rt/lib/scudo/standalone/common.h index e5dfda2e9072..8adcebd55698 100644 --- a/compiler-rt/lib/scudo/standalone/common.h +++ b/compiler-rt/lib/scudo/standalone/common.h @@ -148,6 +148,10 @@ inline constexpr uptr getPageSizeLogCached() { extern uptr PageSizeCached; extern uptr PageSizeLogCached; +// Must be defined in platform specific code. +uptr getPageSize(); + +// Always calls getPageSize(), but caches the results for get*Cached(), below. uptr getPageSizeSlow(); inline uptr getPageSizeCached() { diff --git a/compiler-rt/lib/scudo/standalone/tests/quarantine_test.cpp b/compiler-rt/lib/scudo/standalone/tests/quarantine_test.cpp index 972c98d510a9..54d42edc374e 100644 --- a/compiler-rt/lib/scudo/standalone/tests/quarantine_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/quarantine_test.cpp @@ -6,16 +6,18 @@ // //===----------------------------------------------------------------------===// -#include "tests/scudo_unit_test.h" - #include "quarantine.h" #include <pthread.h> #include <stdlib.h> -static void *FakePtr = reinterpret_cast<void *>(0xFA83FA83); -static const scudo::uptr BlockSize = 8UL; -static const scudo::uptr LargeBlockSize = 16384UL; +#include "tests/scudo_unit_test.h" + +namespace { + +void *FakePtr = reinterpret_cast<void *>(0xFA83FA83); +const scudo::uptr BlockSize = 8UL; +const scudo::uptr LargeBlockSize = 16384UL; struct QuarantineCallback { void recycle(void *P) { EXPECT_EQ(P, FakePtr); } @@ -26,9 +28,9 @@ struct QuarantineCallback { typedef scudo::GlobalQuarantine<QuarantineCallback, void> QuarantineT; typedef typename QuarantineT::CacheT CacheT; -static QuarantineCallback Cb; +QuarantineCallback Cb; -static void deallocateCache(CacheT *Cache) { +void deallocateCache(CacheT *Cache) { while (scudo::QuarantineBatch *Batch = Cache->dequeueBatch()) Cb.deallocate(Batch); } @@ -187,8 +189,8 @@ TEST(ScudoQuarantineTest, QuarantineCacheMergeBatchesALotOfBatches) { deallocateCache(&ToDeallocate); } -static const scudo::uptr MaxQuarantineSize = 1024UL << 10; // 1MB -static const scudo::uptr MaxCacheSize = 256UL << 10; // 256KB +const scudo::uptr MaxQuarantineSize = 1024UL << 10; // 1MB +const scudo::uptr MaxCacheSize = 256UL << 10; // 256KB TEST(ScudoQuarantineTest, GlobalQuarantine) { QuarantineT Quarantine; @@ -253,3 +255,5 @@ TEST(ScudoQuarantineTest, ThreadedGlobalQuarantine) { for (scudo::uptr I = 0; I < NumberOfThreads; I++) Quarantine.drainAndRecycle(&T[I].Cache, Cb); } + +} // namespace diff --git a/compiler-rt/lib/tsan/go/test.c b/compiler-rt/lib/tsan/go/test.c index 1b0d828c9044..d328ab1b331d 100644 --- a/compiler-rt/lib/tsan/go/test.c +++ b/compiler-rt/lib/tsan/go/test.c @@ -63,6 +63,13 @@ int main(void) { __tsan_init(&thr0, &proc0, symbolize_cb); current_proc = proc0; +#if defined(__riscv) && (__riscv_xlen == 64) && defined(__linux__) + // Use correct go_heap for riscv64 sv39. + if (65 - __builtin_clzl((unsigned long)__builtin_frame_address(0)) == 39) { + go_heap = (void *)0x511100000; + } +#endif + // Allocate something resembling a heap in Go. buf0 = mmap(go_heap, 16384, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_ANON, -1, 0); diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform.h b/compiler-rt/lib/tsan/rtl/tsan_platform.h index ada594bc11fc..00b493bf2d93 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_platform.h +++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h @@ -681,6 +681,32 @@ struct MappingGoMips64_47 { static const uptr kShadowAdd = 0x200000000000ull; }; +/* Go on linux/riscv64 (39-bit VMA) +0000 0001 0000 - 000f 0000 0000: executable and heap (60 GiB) +000f 0000 0000 - 0010 0000 0000: - +0010 0000 0000 - 0030 0000 0000: shadow - 128 GiB ( ~ 2 * app) +0030 0000 0000 - 0038 0000 0000: metainfo - 32 GiB ( ~ 0.5 * app) +0038 0000 0000 - 0040 0000 0000: - +*/ +struct MappingGoRiscv64_39 { + static const uptr kMetaShadowBeg = 0x003000000000ull; + static const uptr kMetaShadowEnd = 0x003800000000ull; + static const uptr kShadowBeg = 0x001000000000ull; + static const uptr kShadowEnd = 0x003000000000ull; + static const uptr kLoAppMemBeg = 0x000000010000ull; + static const uptr kLoAppMemEnd = 0x000f00000000ull; + static const uptr kMidAppMemBeg = 0; + static const uptr kMidAppMemEnd = 0; + static const uptr kHiAppMemBeg = 0; + static const uptr kHiAppMemEnd = 0; + static const uptr kHeapMemBeg = 0; + static const uptr kHeapMemEnd = 0; + static const uptr kVdsoBeg = 0; + static const uptr kShadowMsk = 0; + static const uptr kShadowXor = 0; + static const uptr kShadowAdd = 0x001000000000ull; +}; + /* Go on linux/riscv64 (48-bit VMA) 0000 0001 0000 - 00e0 0000 0000: executable and heap (896 GiB) 00e0 0000 0000 - 2000 0000 0000: - @@ -689,13 +715,13 @@ struct MappingGoMips64_47 { 3000 0000 0000 - 3100 0000 0000: metainfo - 1 TiB ( ~ 1 * app) 3100 0000 0000 - 8000 0000 0000: - */ -struct MappingGoRiscv64 { +struct MappingGoRiscv64_48 { static const uptr kMetaShadowBeg = 0x300000000000ull; static const uptr kMetaShadowEnd = 0x310000000000ull; static const uptr kShadowBeg = 0x200000000000ull; static const uptr kShadowEnd = 0x240000000000ull; static const uptr kLoAppMemBeg = 0x000000010000ull; - static const uptr kLoAppMemEnd = 0x000e00000000ull; + static const uptr kLoAppMemEnd = 0x00e000000000ull; static const uptr kMidAppMemBeg = 0; static const uptr kMidAppMemEnd = 0; static const uptr kHiAppMemBeg = 0; @@ -756,7 +782,12 @@ ALWAYS_INLINE auto SelectMapping(Arg arg) { # elif defined(__loongarch_lp64) return Func::template Apply<MappingGoLoongArch64_47>(arg); # elif SANITIZER_RISCV64 - return Func::template Apply<MappingGoRiscv64>(arg); + switch (vmaSize) { + case 39: + return Func::template Apply<MappingGoRiscv64_39>(arg); + case 48: + return Func::template Apply<MappingGoRiscv64_48>(arg); + } # elif SANITIZER_WINDOWS return Func::template Apply<MappingGoWindows>(arg); # else @@ -827,7 +858,8 @@ void ForEachMapping() { Func::template Apply<MappingGoAarch64>(); Func::template Apply<MappingGoLoongArch64_47>(); Func::template Apply<MappingGoMips64_47>(); - Func::template Apply<MappingGoRiscv64>(); + Func::template Apply<MappingGoRiscv64_39>(); + Func::template Apply<MappingGoRiscv64_48>(); Func::template Apply<MappingGoS390x>(); } diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp index 2c55645a1547..4b55aab49a2b 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cpp @@ -393,9 +393,9 @@ void InitializePlatformEarly() { Die(); } # else - if (vmaSize != 48) { + if (vmaSize != 39 && vmaSize != 48) { Printf("FATAL: ThreadSanitizer: unsupported VMA range\n"); - Printf("FATAL: Found %zd - Supported 48\n", vmaSize); + Printf("FATAL: Found %zd - Supported 39 and 48\n", vmaSize); Die(); } # endif diff --git a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp index 1e143075f1be..a2a2e36e8523 100644 --- a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp +++ b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp @@ -125,13 +125,15 @@ void NORETURN CheckFailed(const char *file, int, const char *cond, u64, u64) { } // namespace __sanitizer #endif +#define INTERFACE extern "C" __attribute__((visibility("default"))) + #define HANDLER_RECOVER(name, kind) \ - SANITIZER_INTERFACE_WEAK_DEF(void, __ubsan_handle_##name##_minimal) { \ + INTERFACE void __ubsan_handle_##name##_minimal() { \ __ubsan_report_error(kind, GET_CALLER_PC(), nullptr); \ } #define HANDLER_NORECOVER(name, kind) \ - SANITIZER_INTERFACE_WEAK_DEF(void, __ubsan_handle_##name##_minimal_abort) { \ + INTERFACE void __ubsan_handle_##name##_minimal_abort() { \ uintptr_t caller = GET_CALLER_PC(); \ __ubsan_report_error_fatal(kind, caller, nullptr); \ abort_with_message(kind, caller, nullptr); \ @@ -142,14 +144,13 @@ void NORETURN CheckFailed(const char *file, int, const char *cond, u64, u64) { HANDLER_NORECOVER(name, kind) #define HANDLER_RECOVER_PTR(name, kind) \ - SANITIZER_INTERFACE_WEAK_DEF(void, __ubsan_handle_##name##_minimal, \ - const uintptr_t address) { \ + INTERFACE void __ubsan_handle_##name##_minimal(const uintptr_t address) { \ __ubsan_report_error(kind, GET_CALLER_PC(), &address); \ } #define HANDLER_NORECOVER_PTR(name, kind) \ - SANITIZER_INTERFACE_WEAK_DEF(void, __ubsan_handle_##name##_minimal_abort, \ - const uintptr_t address) { \ + INTERFACE void __ubsan_handle_##name##_minimal_abort( \ + const uintptr_t address) { \ uintptr_t caller = GET_CALLER_PC(); \ __ubsan_report_error_fatal(kind, caller, &address); \ abort_with_message(kind, caller, &address); \ diff --git a/compiler-rt/test/asan/TestCases/Darwin/duplicate_os_log_reports.cpp b/compiler-rt/test/asan/TestCases/Darwin/duplicate_os_log_reports.cpp index 43ca027c970c..0091ebc09205 100644 --- a/compiler-rt/test/asan/TestCases/Darwin/duplicate_os_log_reports.cpp +++ b/compiler-rt/test/asan/TestCases/Darwin/duplicate_os_log_reports.cpp @@ -1,5 +1,4 @@ // UNSUPPORTED: ios -// REQUIRES: shell // REQUIRES: darwin_log_cmd // RUN: %clangxx_asan -fsanitize-recover=address %s -o %t // RUN: { %env_asan_opts=halt_on_error=0,log_to_syslog=1 %run %t > %t.process_output.txt 2>&1 & } \ diff --git a/compiler-rt/test/asan/TestCases/Linux/read_binary_name_regtest.c b/compiler-rt/test/asan/TestCases/Linux/read_binary_name_regtest.c index 08bf5e125cf4..5d4a812c80d8 100644 --- a/compiler-rt/test/asan/TestCases/Linux/read_binary_name_regtest.c +++ b/compiler-rt/test/asan/TestCases/Linux/read_binary_name_regtest.c @@ -6,8 +6,7 @@ // will be unable to resolve its $ORIGIN due to readlink() restriction and will // thus fail to start, causing the test to die with SIGPIPE when attempting to // talk to it. -// RUN: not ls /usr/include/linux/seccomp.h || ( %clang_asan %s -o %t && ( not env ASAN_OPTIONS=symbolize=0 %run %t 2>&1 ) | FileCheck %s ) -// REQUIRES: shell +// RUN: not ls /usr/include/linux/seccomp.h || %clang_asan %s -o %t || not env ASAN_OPTIONS=symbolize=0 %run %t 2>&1 | FileCheck %s // UNSUPPORTED: android #include <errno.h> diff --git a/compiler-rt/test/asan/TestCases/Windows/heaprealloc_alloc_zero.cpp b/compiler-rt/test/asan/TestCases/Windows/heaprealloc_alloc_zero.cpp index 8b0bc71b9f5d..6a5f8a1e7ea0 100644 --- a/compiler-rt/test/asan/TestCases/Windows/heaprealloc_alloc_zero.cpp +++ b/compiler-rt/test/asan/TestCases/Windows/heaprealloc_alloc_zero.cpp @@ -1,15 +1,20 @@ // RUN: %clang_cl_asan %Od %MT -o %t %s // RUN: %env_asan_opts=windows_hook_rtl_allocators=true %run %t 2>&1 | FileCheck %s -// UNSUPPORTED: asan-64-bits #include <cassert> #include <iostream> +#include <sanitizer/allocator_interface.h> #include <windows.h> int main() { void *ptr = malloc(0); if (ptr) std::cerr << "allocated!\n"; - ((char *)ptr)[0] = '\xff'; //check this 'allocate 1 instead of 0' hack hasn't changed + + // Check the 'allocate 1 instead of 0' hack hasn't changed + // Note that as of b3452d90b043a398639e62b0ab01aa339cc649de, dereferencing + // the pointer will be detected as a heap-buffer-overflow. + if (__sanitizer_get_allocated_size(ptr) != 1) + return 1; free(ptr); diff --git a/compiler-rt/test/asan/TestCases/Windows/rtlallocateheap_realloc_in_place.cpp b/compiler-rt/test/asan/TestCases/Windows/rtlallocateheap_realloc_in_place.cpp new file mode 100644 index 000000000000..35fa9ce57429 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/Windows/rtlallocateheap_realloc_in_place.cpp @@ -0,0 +1,71 @@ +// RUN: %clang_cl_asan %Od %s %Fe%t %MD +// RUN: %env_asan_opts=windows_hook_rtl_allocators=true not %run %t 2>&1 | FileCheck %s + +#include <stdio.h> +#include <windows.h> + +using AllocateFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, SIZE_T); +using ReAllocateFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, PVOID, SIZE_T); +using FreeFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, PVOID); + +int main() { + HMODULE NtDllHandle = GetModuleHandle("ntdll.dll"); + if (!NtDllHandle) { + fputs("Couldn't load ntdll??\n", stderr); + return -1; + } + + auto RtlAllocateHeap_ptr = + (AllocateFunctionPtr)GetProcAddress(NtDllHandle, "RtlAllocateHeap"); + if (RtlAllocateHeap_ptr == 0) { + fputs("Couldn't RtlAllocateHeap\n", stderr); + return -1; + } + + auto RtlReAllocateHeap_ptr = + (ReAllocateFunctionPtr)GetProcAddress(NtDllHandle, "RtlReAllocateHeap"); + if (RtlReAllocateHeap_ptr == 0) { + fputs("Couldn't find RtlReAllocateHeap\n", stderr); + return -1; + } + + auto RtlFreeHeap_ptr = + (FreeFunctionPtr)GetProcAddress(NtDllHandle, "RtlFreeHeap"); + if (RtlFreeHeap_ptr == 0) { + fputs("Couldn't RtlFreeHeap\n", stderr); + return -1; + } + + char *ptr1; + char *ptr2; + ptr2 = ptr1 = (char *)RtlAllocateHeap_ptr(GetProcessHeap(), 0, 15); + if (ptr1) + fputs("Okay alloc\n", stderr); + // CHECK: Okay alloc + + // TODO: Growing is currently not supported + ptr2 = (char *)RtlReAllocateHeap_ptr(GetProcessHeap(), + HEAP_REALLOC_IN_PLACE_ONLY, ptr1, 23); + if (ptr2 == NULL) + fputs("Okay grow failed\n", stderr); + // CHECK: Okay grow failed + + // TODO: Shrinking is currently not supported + ptr2 = (char *)RtlReAllocateHeap_ptr(GetProcessHeap(), + HEAP_REALLOC_IN_PLACE_ONLY, ptr1, 7); + if (ptr2 == ptr1) + fputs("Okay shrinking return the original pointer\n", stderr); + // CHECK: Okay shrinking return the original pointer + + ptr1[7] = 'a'; + fputs("Okay 7\n", stderr); + // CHECK: Okay 7 + + // TODO: Writing behind the shrinked part is currently not detected. + // Therefore test writing behind the original allocation for now. + ptr1[16] = 'a'; + // CHECK: AddressSanitizer: heap-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] + // CHECK: WRITE of size 1 at [[ADDR]] thread T0 + + RtlFreeHeap_ptr(GetProcessHeap(), 0, ptr1); +} diff --git a/compiler-rt/test/asan/TestCases/suppressions-library.cpp b/compiler-rt/test/asan/TestCases/suppressions-library.cpp index 5427122eaa92..9d1f5d4888e3 100644 --- a/compiler-rt/test/asan/TestCases/suppressions-library.cpp +++ b/compiler-rt/test/asan/TestCases/suppressions-library.cpp @@ -4,8 +4,6 @@ // Check that without suppressions, we catch the issue. // RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s -// REQUIRES: shell - // RUN: echo "interceptor_via_lib:"%xdynamiclib_filename > %t.supp // RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s diff --git a/compiler-rt/test/asan/TestCases/verbose-log-path_test.cpp b/compiler-rt/test/asan/TestCases/verbose-log-path_test.cpp index 37c1dab6db8e..2c094c484371 100644 --- a/compiler-rt/test/asan/TestCases/verbose-log-path_test.cpp +++ b/compiler-rt/test/asan/TestCases/verbose-log-path_test.cpp @@ -1,9 +1,6 @@ // RUN: rm -rf %t-dir && mkdir -p %t-dir // RUN: %clangxx_asan %s -o %t-dir/verbose-log-path_test-binary -// The glob below requires bash. -// REQUIRES: shell - // Good log_path. // RUN: rm -f %t-dir/asan.log.* // RUN: %env_asan_opts=log_path=%t-dir/asan.log:log_exe_name=1 not %run %t-dir/verbose-log-path_test-binary 2> %t.out diff --git a/compiler-rt/test/asan/TestCases/zero_alloc.cpp b/compiler-rt/test/asan/TestCases/zero_alloc.cpp new file mode 100644 index 000000000000..aa807f44ed3b --- /dev/null +++ b/compiler-rt/test/asan/TestCases/zero_alloc.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_asan -Wno-alloc-size -fsanitize-recover=address %s -o %t && %env_asan_opts=halt_on_error=0 %run %t 2>&1 | FileCheck %s + +#include <stdio.h> +#include <stdlib.h> + +int main(int argc, char **argv) { + { + char *p1 = (char *)calloc(1, 0); + printf("p1 is %p\n", p1); + printf("Content of p1 is: %d\n", *p1); + // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow + // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]] + free(p1); + } + + { + char *p2 = (char *)calloc(0, 1); + printf("p2 is %p\n", p2); + printf("Content of p2 is: %d\n", *p2); + // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow + // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]] + free(p2); + } + + { + char *p3 = (char *)malloc(0); + printf("p3 is %p\n", p3); + printf("Content of p2 is: %d\n", *p3); + // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow + // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]] + free(p3); + } + + return 0; +} diff --git a/compiler-rt/test/fuzzer/CrossOverTest.cpp b/compiler-rt/test/fuzzer/CrossOverTest.cpp index b4506f665dc7..eb8a8c44ad47 100644 --- a/compiler-rt/test/fuzzer/CrossOverTest.cpp +++ b/compiler-rt/test/fuzzer/CrossOverTest.cpp @@ -45,6 +45,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { // fprintf(stderr, "ExpectedHash: %x\n", ExpectedHash); if (Size == 10 && ExpectedHash == simple_hash(Data, Size)) *NullPtr = 0; + // It's UB to read *Data when Size == 0 + if (Size == 0) + return 0; if (*Data == 'A') Sink++; if (*Data == 'Z') diff --git a/compiler-rt/test/fuzzer/sig-trap.test b/compiler-rt/test/fuzzer/sig-trap.test index 30d9d47f4d81..60208c486a87 100644 --- a/compiler-rt/test/fuzzer/sig-trap.test +++ b/compiler-rt/test/fuzzer/sig-trap.test @@ -5,7 +5,7 @@ UNSUPPORTED: target={{.*windows.*}} RUN: %cpp_compiler %S/SigTrapTest.cpp -o %t RUN: not %run %t 2>&1 | FileCheck %s -CHECK: BINGO -CHECK: ERROR: libFuzzer: deadly signal +CHECK-DAG: BINGO +CHECK-DAG: ERROR: libFuzzer: deadly signal RUN: trap "%run %t -handle_trap=0" TRAP diff --git a/compiler-rt/test/hwasan/TestCases/Posix/dlerror.cpp b/compiler-rt/test/hwasan/TestCases/Posix/dlerror.cpp index 91acd28a1a5f..b045ec704cec 100644 --- a/compiler-rt/test/hwasan/TestCases/Posix/dlerror.cpp +++ b/compiler-rt/test/hwasan/TestCases/Posix/dlerror.cpp @@ -4,7 +4,7 @@ // Android HWAsan does not support LSan. // UNSUPPORTED: android -// RUN: %clangxx_hwasan -O0 %s -o %t && HWASAN_OPTIONS=detect_leaks=1 %run %t +// RUN: %clangxx_hwasan -O0 %s -o %t && env HWASAN_OPTIONS=detect_leaks=1 %run %t #include <assert.h> #include <dlfcn.h> diff --git a/compiler-rt/test/msan/zero_alloc.cpp b/compiler-rt/test/msan/zero_alloc.cpp new file mode 100644 index 000000000000..1451e1e89e9f --- /dev/null +++ b/compiler-rt/test/msan/zero_alloc.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_msan -Wno-alloc-size -fsanitize-recover=memory %s -o %t && not %run %t 2>&1 | FileCheck %s + +#include <stdio.h> +#include <stdlib.h> + +int main(int argc, char **argv) { + { + char *p1 = (char *)calloc(1, 0); + printf("p1 is %p\n", p1); + printf("Content of p1 is: %d\n", *p1); + // CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value + // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]] + free(p1); + } + + { + char *p2 = (char *)calloc(0, 1); + printf("p2 is %p\n", p2); + printf("Content of p2 is: %d\n", *p2); + // CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value + // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]] + free(p2); + } + + { + char *p3 = (char *)malloc(0); + printf("p3 is %p\n", p3); + printf("Content of p2 is: %d\n", *p3); + // CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value + // CHECK: {{#0 0x.* in main .*zero_alloc.cpp:}}[[@LINE-2]] + free(p3); + } + + return 0; +} diff --git a/compiler-rt/test/profile/instrprof-thinlto-indirect-call-promotion.cpp b/compiler-rt/test/profile/instrprof-thinlto-indirect-call-promotion.cpp index d361186cf26a..4509c0149bdb 100644 --- a/compiler-rt/test/profile/instrprof-thinlto-indirect-call-promotion.cpp +++ b/compiler-rt/test/profile/instrprof-thinlto-indirect-call-promotion.cpp @@ -80,7 +80,7 @@ static void callee0() {} void callee1() {} typedef void (*FPT)(); FPT calleeAddrs[] = {callee0, callee1}; -// `global_func`` might call one of two indirect callees. callee0 has internal +// `global_func` might call one of two indirect callees. callee0 has internal // linkage and callee1 has external linkage. void global_func() { FPT fp = calleeAddrs[0]; diff --git a/compiler-rt/test/rtsan/unrecognized_flags.cpp b/compiler-rt/test/rtsan/unrecognized_flags.cpp index 9e44e9f42993..d6649db6b0fb 100644 --- a/compiler-rt/test/rtsan/unrecognized_flags.cpp +++ b/compiler-rt/test/rtsan/unrecognized_flags.cpp @@ -1,5 +1,5 @@ // RUN: %clangxx -fsanitize=realtime %s -o %t -// RUN: RTSAN_OPTIONS="verbosity=1,asdf=1" %run %t 2>&1 | FileCheck %s +// RUN: env RTSAN_OPTIONS="verbosity=1,asdf=1" %run %t 2>&1 | FileCheck %s // UNSUPPORTED: ios // Intent: Make sure we are respecting some basic common flags diff --git a/compiler-rt/test/sanitizer_common/TestCases/external_symbolizer_path.cpp b/compiler-rt/test/sanitizer_common/TestCases/external_symbolizer_path.cpp index 9416da2940be..45e8eaddb024 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/external_symbolizer_path.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/external_symbolizer_path.cpp @@ -19,8 +19,6 @@ // RUN: %env_tool_opts=external_symbolizer_path=%d/external_symbolizer_path.cpp.tmp.bin/llvm-symbolizer \ // RUN: %run %t 2>&1 | FileCheck %s --check-prefix=NOT-FOUND -// REQUIRES: shell - // Mobile device will not have symbolizer in provided path. // UNSUPPORTED: ios, android diff --git a/compiler-rt/test/sanitizer_common/TestCases/suffix-log-path_test.c b/compiler-rt/test/sanitizer_common/TestCases/suffix-log-path_test.c index bf0e4e1bc376..b8ca5c739f42 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/suffix-log-path_test.c +++ b/compiler-rt/test/sanitizer_common/TestCases/suffix-log-path_test.c @@ -2,9 +2,6 @@ // RUN: mkdir -p %t.dir // RUN: %clang %s -o %t.dir/suffix-log-path_test-binary -// The glob below requires bash. -// REQUIRES: shell - // Good log_path with suffix. // RUN: %env_tool_opts=log_path=%t.dir/sanitizer.log:log_exe_name=1:log_suffix=.txt %run %t.dir/suffix-log-path_test-binary 2> %t.out // RUN: FileCheck %s < %t.dir/sanitizer.log.suffix-log-path_test-binary.*.txt diff --git a/compiler-rt/test/ubsan/TestCases/Misc/coverage-levels.cpp b/compiler-rt/test/ubsan/TestCases/Misc/coverage-levels.cpp index 527bd8552c81..e1191b5f6bb9 100644 --- a/compiler-rt/test/ubsan/TestCases/Misc/coverage-levels.cpp +++ b/compiler-rt/test/ubsan/TestCases/Misc/coverage-levels.cpp @@ -1,8 +1,5 @@ // Test various levels of coverage // -// FIXME: Port the environment variable logic below for the lit shell. -// REQUIRES: shell -// // RUN: rm -rf %t-dir && mkdir %t-dir // RUN: %clangxx -fsanitize=shift -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=func,trace-pc-guard %s -o %t // RUN: %env_ubsan_opts=coverage=1:verbosity=1:coverage_dir='"%t-dir"' %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN diff --git a/compiler-rt/test/ubsan/TestCases/Misc/log-path_test.cpp b/compiler-rt/test/ubsan/TestCases/Misc/log-path_test.cpp index ffd95a5f9c0b..f1618afba248 100644 --- a/compiler-rt/test/ubsan/TestCases/Misc/log-path_test.cpp +++ b/compiler-rt/test/ubsan/TestCases/Misc/log-path_test.cpp @@ -1,9 +1,6 @@ // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 // XFAIL: android -// The globs below do not work in the lit shell. -// REQUIRES: shell - // RUN: %clangxx -fsanitize=undefined %s -O1 -o %t // Regular run. @@ -38,4 +35,3 @@ int main(int argc, char *argv[]) { } // CHECK-ERROR: runtime error: -4 is outside the range of representable values of type 'unsigned int' - diff --git a/compiler-rt/test/xray/TestCases/Posix/dlopen.cpp b/compiler-rt/test/xray/TestCases/Posix/dlopen.cpp index 9567269e8ff1..5326d83dfdd7 100644 --- a/compiler-rt/test/xray/TestCases/Posix/dlopen.cpp +++ b/compiler-rt/test/xray/TestCases/Posix/dlopen.cpp @@ -5,7 +5,7 @@ // RUN: %clangxx_xray -g -fPIC -fxray-instrument -fxray-shared -shared -std=c++11 %t/testlib.cpp -o %t/testlib.so // RUN: %clangxx_xray -g -fPIC -rdynamic -fxray-instrument -fxray-shared -std=c++11 %t/main.cpp -o %t/main.o // -// RUN: XRAY_OPTIONS="patch_premain=true" %run %t/main.o %t/testlib.so 2>&1 | FileCheck %s +// RUN: env XRAY_OPTIONS="patch_premain=true" %run %t/main.o %t/testlib.so 2>&1 | FileCheck %s // REQUIRES: target={{(aarch64|x86_64)-.*}} diff --git a/compiler-rt/test/xray/TestCases/Posix/dso-dep-chains.cpp b/compiler-rt/test/xray/TestCases/Posix/dso-dep-chains.cpp index 82cc127b521a..3b4564306abd 100644 --- a/compiler-rt/test/xray/TestCases/Posix/dso-dep-chains.cpp +++ b/compiler-rt/test/xray/TestCases/Posix/dso-dep-chains.cpp @@ -15,7 +15,7 @@ // Executable links with a and b explicitly and loads d and e at runtime. // RUN: %clangxx_xray -g -fPIC -rdynamic -fxray-instrument -fxray-shared -std=c++11 %t/main.cpp %t/testliba.so %t/testlibb.so -o %t/main.o // -// RUN: XRAY_OPTIONS="patch_premain=true" %run %t/main.o %t/testlibd.so %t/testlibe.so 2>&1 | FileCheck %s +// RUN: env XRAY_OPTIONS="patch_premain=true" %run %t/main.o %t/testlibd.so %t/testlibe.so 2>&1 | FileCheck %s // REQUIRES: target={{(aarch64|x86_64)-.*}} diff --git a/compiler-rt/test/xray/TestCases/Posix/patch-premain-dso.cpp b/compiler-rt/test/xray/TestCases/Posix/patch-premain-dso.cpp index 7bce653fe723..5014fce61d5b 100644 --- a/compiler-rt/test/xray/TestCases/Posix/patch-premain-dso.cpp +++ b/compiler-rt/test/xray/TestCases/Posix/patch-premain-dso.cpp @@ -4,7 +4,7 @@ // RUN: %clangxx_xray -g -fPIC -fxray-instrument -fxray-shared -shared -std=c++11 %t/testlib.cpp -o %t/testlib.so // RUN: %clangxx_xray -g -fPIC -fxray-instrument -fxray-shared -std=c++11 %t/main.cpp %t/testlib.so -Wl,-rpath,%t -o %t/main.o -// RUN: XRAY_OPTIONS="patch_premain=true,verbosity=1" %run %t/main.o 2>&1 | FileCheck %s +// RUN: env XRAY_OPTIONS="patch_premain=true,verbosity=1" %run %t/main.o 2>&1 | FileCheck %s // REQUIRES: target={{(aarch64|x86_64)-.*}} diff --git a/compiler-rt/test/xray/TestCases/Posix/patching-unpatching-dso.cpp b/compiler-rt/test/xray/TestCases/Posix/patching-unpatching-dso.cpp index 640cf9bcc1a3..9b3f63b5368a 100644 --- a/compiler-rt/test/xray/TestCases/Posix/patching-unpatching-dso.cpp +++ b/compiler-rt/test/xray/TestCases/Posix/patching-unpatching-dso.cpp @@ -6,7 +6,7 @@ // RUN: %clangxx_xray -g -fPIC -fxray-instrument -fxray-shared -shared -std=c++11 %t/testlib.cpp -o %t/testlib.so // RUN: %clangxx_xray -g -fPIC -fxray-instrument -fxray-shared -std=c++11 %t/main.cpp %t/testlib.so -Wl,-rpath,%t -o %t/main.o -// RUN: XRAY_OPTIONS="patch_premain=false" %run %t/main.o 2>&1 | FileCheck %s +// RUN: env XRAY_OPTIONS="patch_premain=false" %run %t/main.o 2>&1 | FileCheck %s // REQUIRES: target={{(aarch64|x86_64)-.*}} |
