diff --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp index 3a55c2af65653..eecf3788c0a6f 100644 --- a/compiler-rt/lib/asan/asan_allocator.cpp +++ b/compiler-rt/lib/asan/asan_allocator.cpp @@ -770,11 +770,17 @@ struct Allocator { u8 chunk_state = atomic_load(&m->chunk_state, memory_order_acquire); if (chunk_state != CHUNK_ALLOCATED) ReportInvalidFree(old_ptr, chunk_state, stack); - CHECK_NE(REAL(memcpy), nullptr); uptr memcpy_size = Min(new_size, m->UsedSize()); // If realloc() races with free(), we may start copying freed memory. // However, we will report racy double-free later anyway. +#if !SANITIZER_AIX + CHECK_NE(REAL(memcpy), nullptr); REAL(memcpy)(new_ptr, old_ptr, memcpy_size); +#else + // AIX currently can't retrieve memcpy's address, we have to use + // internal_memcpy here. + internal_memcpy(new_ptr, old_ptr, memcpy_size); +#endif Deallocate(old_ptr, 0, 0, stack, FROM_MALLOC); } return new_ptr; diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp index 7c9a08b9083a2..9c95df2798a60 100644 --- a/compiler-rt/lib/asan/asan_interceptors.cpp +++ b/compiler-rt/lib/asan/asan_interceptors.cpp @@ -56,8 +56,18 @@ namespace __asan { # define ASAN_READ_STRING(ctx, s, n) \ ASAN_READ_STRING_OF_LEN((ctx), (s), internal_strlen(s), (n)) -static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) { -#if SANITIZER_INTERCEPT_STRNLEN +static inline void internal_or_real_memcpy(void *new_mem, const char *s, + uptr length) { +# if SANITIZER_INTERCEPT_MEMCPY + REAL(memcpy)(new_mem, s, length + 1); +# else + internal_memcpy(new_mem, s, length + 1); +# endif +} + +[[maybe_unused]] static inline uptr MaybeRealStrnlen(const char *s, + uptr maxlen) { +# if SANITIZER_INTERCEPT_STRNLEN if (REAL(strnlen)) { return REAL(strnlen)(s, maxlen); } @@ -275,7 +285,12 @@ INTERCEPTOR(int, pthread_create, void *thread, void *attr, # endif asanThreadArgRetval().Create(detached, {start_routine, arg}, [&]() -> uptr { result = REAL(pthread_create)(thread, attr, asan_thread_start, t); +// AIX pthread_t is unsigned int. +# if SANITIZER_AIX + return result ? 0 : *(unsigned *)(thread); +# else return result ? 0 : *(uptr *)(thread); +# endif }); } if (result != 0) { @@ -432,12 +447,14 @@ INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp, #define siglongjmp __siglongjmp14 #endif +# if ASAN_INTERCEPT_LONGJMP INTERCEPTOR(void, longjmp, void *env, int val) { __asan_handle_no_return(); REAL(longjmp)(env, val); } +# endif -#if ASAN_INTERCEPT__LONGJMP +# if ASAN_INTERCEPT__LONGJMP INTERCEPTOR(void, _longjmp, void *env, int val) { __asan_handle_no_return(); REAL(_longjmp)(env, val); @@ -508,6 +525,7 @@ DEFINE_REAL(char*, index, const char *string, int c) // For both strcat() and strncat() we need to check the validity of |to| // argument irrespective of the |from| length. +# if ASAN_INTERCEPT_STRCAT INTERCEPTOR(char *, strcat, char *to, const char *from) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, strcat); @@ -547,7 +565,9 @@ INTERCEPTOR(char*, strncat, char *to, const char *from, usize size) { } return REAL(strncat)(to, from, size); } +# endif +# if ASAN_INTERCEPT_STRCPY INTERCEPTOR(char *, strcpy, char *to, const char *from) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, strcpy); @@ -569,6 +589,7 @@ INTERCEPTOR(char *, strcpy, char *to, const char *from) { } return REAL(strcpy)(to, from); } +# endif // Windows doesn't always define the strdup identifier, // and when it does it's a macro defined to either _strdup @@ -596,7 +617,7 @@ INTERCEPTOR(char*, strdup, const char *s) { GET_STACK_TRACE_MALLOC; void *new_mem = asan_malloc(length + 1, &stack); if (new_mem) { - REAL(memcpy)(new_mem, s, length + 1); + internal_or_real_memcpy(new_mem, s, length + 1); } return reinterpret_cast(new_mem); } @@ -614,12 +635,13 @@ INTERCEPTOR(char*, __strdup, const char *s) { GET_STACK_TRACE_MALLOC; void *new_mem = asan_malloc(length + 1, &stack); if (new_mem) { - REAL(memcpy)(new_mem, s, length + 1); + internal_or_real_memcpy(new_mem, s, length + 1); } return reinterpret_cast(new_mem); } #endif // ASAN_INTERCEPT___STRDUP +# if ASAN_INTERCEPT_STRCPY INTERCEPTOR(char*, strncpy, char *to, const char *from, usize size) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, strncpy); @@ -632,6 +654,7 @@ INTERCEPTOR(char*, strncpy, char *to, const char *from, usize size) { } return REAL(strncpy)(to, from, size); } +# endif template static ALWAYS_INLINE auto StrtolImpl(void *ctx, Fn real, const char *nptr, @@ -743,7 +766,15 @@ static void AtCxaAtexit(void *unused) { } #endif -#if ASAN_INTERCEPT___CXA_ATEXIT +# if ASAN_INTERCEPT_EXIT +INTERCEPTOR(void, exit, int status) { + AsanInitFromRtl(); + StopInitOrderChecking(); + REAL(exit)(status); +} +# endif + +# if ASAN_INTERCEPT___CXA_ATEXIT INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, void *dso_handle) { if (SANITIZER_APPLE && UNLIKELY(!AsanInited())) @@ -804,10 +835,14 @@ void InitializeAsanInterceptors() { InitializeSignalInterceptors(); // Intercept str* functions. +# if ASAN_INTERCEPT_STRCAT ASAN_INTERCEPT_FUNC(strcat); - ASAN_INTERCEPT_FUNC(strcpy); ASAN_INTERCEPT_FUNC(strncat); +# endif +# if ASAN_INTERCEPT_STRCPY + ASAN_INTERCEPT_FUNC(strcpy); ASAN_INTERCEPT_FUNC(strncpy); +# endif ASAN_INTERCEPT_FUNC(strdup); # if ASAN_INTERCEPT___STRDUP ASAN_INTERCEPT_FUNC(__strdup); @@ -827,7 +862,9 @@ void InitializeAsanInterceptors() { # endif // Intercept jump-related functions. +# if ASAN_INTERCEPT_LONGJMP ASAN_INTERCEPT_FUNC(longjmp); +# endif # if ASAN_INTERCEPT_SWAPCONTEXT ASAN_INTERCEPT_FUNC(swapcontext); @@ -894,7 +931,11 @@ void InitializeAsanInterceptors() { ASAN_INTERCEPT_FUNC(atexit); #endif -#if ASAN_INTERCEPT_PTHREAD_ATFORK +# if ASAN_INTERCEPT_EXIT + ASAN_INTERCEPT_FUNC(exit); +# endif + +# if ASAN_INTERCEPT_PTHREAD_ATFORK ASAN_INTERCEPT_FUNC(pthread_atfork); #endif diff --git a/compiler-rt/lib/asan/asan_interceptors.h b/compiler-rt/lib/asan/asan_interceptors.h index 3e2386eaf8092..013e5af6180ff 100644 --- a/compiler-rt/lib/asan/asan_interceptors.h +++ b/compiler-rt/lib/asan/asan_interceptors.h @@ -31,12 +31,24 @@ void InitializePlatformInterceptors(); // really defined to replace libc functions. #if !SANITIZER_FUCHSIA +// AIX currently can't retrieve the address of longjmp +# if !SANITIZER_AIX +# define ASAN_INTERCEPT_LONGJMP 1 +# else +# define ASAN_INTERCEPT_LONGJMP 0 +# endif + // Use macro to describe if specific function should be // intercepted on a given platform. #if !SANITIZER_WINDOWS -# define ASAN_INTERCEPT__LONGJMP 1 -# define ASAN_INTERCEPT_INDEX 1 -# define ASAN_INTERCEPT_PTHREAD_CREATE 1 + // AIX currently can't retrieve the address of _longjmp +# if !SANITIZER_AIX +# define ASAN_INTERCEPT__LONGJMP 1 +# else +# define ASAN_INTERCEPT__LONGJMP 0 +# endif +# define ASAN_INTERCEPT_INDEX 1 +# define ASAN_INTERCEPT_PTHREAD_CREATE 1 #else # define ASAN_INTERCEPT__LONGJMP 0 # define ASAN_INTERCEPT_INDEX 0 @@ -56,73 +68,90 @@ void InitializePlatformInterceptors(); # define ASAN_INTERCEPT_SWAPCONTEXT 0 #endif -#if !SANITIZER_WINDOWS -# define ASAN_INTERCEPT_SIGLONGJMP 1 -#else -# define ASAN_INTERCEPT_SIGLONGJMP 0 -#endif - -#if SANITIZER_GLIBC -# define ASAN_INTERCEPT___LONGJMP_CHK 1 -#else -# define ASAN_INTERCEPT___LONGJMP_CHK 0 -#endif - -#if ASAN_HAS_EXCEPTIONS && !SANITIZER_SOLARIS && !SANITIZER_NETBSD && \ - (!SANITIZER_WINDOWS || (defined(__MINGW32__) && defined(__i386__))) -# define ASAN_INTERCEPT___CXA_THROW 1 -# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1 -# if defined(_GLIBCXX_SJLJ_EXCEPTIONS) || (SANITIZER_IOS && defined(__arm__)) -# define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 1 -# else -# define ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION 1 -# endif -#else -# define ASAN_INTERCEPT___CXA_THROW 0 -# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 0 -# define ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION 0 -# define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 0 -#endif +// AIX currently can't retrieve the address of siglongjmp +# if !SANITIZER_WINDOWS && !SANITIZER_AIX +# define ASAN_INTERCEPT_SIGLONGJMP 1 +# else +# define ASAN_INTERCEPT_SIGLONGJMP 0 +# endif -#if !SANITIZER_WINDOWS -# define ASAN_INTERCEPT___CXA_ATEXIT 1 -#else -# define ASAN_INTERCEPT___CXA_ATEXIT 0 -#endif +# if SANITIZER_GLIBC +# define ASAN_INTERCEPT___LONGJMP_CHK 1 +# else +# define ASAN_INTERCEPT___LONGJMP_CHK 0 +# endif + +# if ASAN_HAS_EXCEPTIONS && !SANITIZER_SOLARIS && !SANITIZER_NETBSD && \ + (!SANITIZER_WINDOWS || (defined(__MINGW32__) && defined(__i386__))) +# define ASAN_INTERCEPT___CXA_THROW 1 +# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1 +# if defined(_GLIBCXX_SJLJ_EXCEPTIONS) || (SANITIZER_IOS && defined(__arm__)) +# define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 1 +# else +# define ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION 1 +# endif +# else +# define ASAN_INTERCEPT___CXA_THROW 0 +# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 0 +# define ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION 0 +# define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 0 +# endif + +// AIX currently can't retrieve the address of __cxa_atexit +# if !SANITIZER_WINDOWS && !SANITIZER_AIX +# define ASAN_INTERCEPT___CXA_ATEXIT 1 +# else +# define ASAN_INTERCEPT___CXA_ATEXIT 0 +# endif -#if SANITIZER_NETBSD -# define ASAN_INTERCEPT_ATEXIT 1 -#else -# define ASAN_INTERCEPT_ATEXIT 0 -#endif +# if SANITIZER_AIX +# define ASAN_INTERCEPT_EXIT 1 +# else +# define ASAN_INTERCEPT_EXIT 0 +# endif -#if SANITIZER_GLIBC -# define ASAN_INTERCEPT___STRDUP 1 -#else -# define ASAN_INTERCEPT___STRDUP 0 -#endif +# if SANITIZER_NETBSD +# define ASAN_INTERCEPT_ATEXIT 1 +# else +# define ASAN_INTERCEPT_ATEXIT 0 +# endif -#if SANITIZER_GLIBC && ASAN_INTERCEPT_PTHREAD_CREATE -# define ASAN_INTERCEPT_TIMEDJOIN 1 -# define ASAN_INTERCEPT_TRYJOIN 1 -#else -# define ASAN_INTERCEPT_TIMEDJOIN 0 -# define ASAN_INTERCEPT_TRYJOIN 0 -#endif +# if SANITIZER_GLIBC +# define ASAN_INTERCEPT___STRDUP 1 +# else +# define ASAN_INTERCEPT___STRDUP 0 +# endif -#if SANITIZER_LINUX && \ - (defined(__arm__) || defined(__aarch64__) || defined(__i386__) || \ - defined(__x86_64__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64) -# define ASAN_INTERCEPT_VFORK 1 -#else -# define ASAN_INTERCEPT_VFORK 0 -#endif +# if SANITIZER_GLIBC && ASAN_INTERCEPT_PTHREAD_CREATE +# define ASAN_INTERCEPT_TIMEDJOIN 1 +# define ASAN_INTERCEPT_TRYJOIN 1 +# else +# define ASAN_INTERCEPT_TIMEDJOIN 0 +# define ASAN_INTERCEPT_TRYJOIN 0 +# endif + +// AIX currently can't retrieve the address of strcat or strcpy +# if SANITIZER_AIX +# define ASAN_INTERCEPT_STRCAT 0 +# define ASAN_INTERCEPT_STRCPY 0 +# else +# define ASAN_INTERCEPT_STRCAT 1 +# define ASAN_INTERCEPT_STRCPY 1 +# endif + +# if SANITIZER_LINUX && \ + (defined(__arm__) || defined(__aarch64__) || defined(__i386__) || \ + defined(__x86_64__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64) +# define ASAN_INTERCEPT_VFORK 1 +# else +# define ASAN_INTERCEPT_VFORK 0 +# endif -#if SANITIZER_NETBSD -# define ASAN_INTERCEPT_PTHREAD_ATFORK 1 -#else -# define ASAN_INTERCEPT_PTHREAD_ATFORK 0 -#endif +# if SANITIZER_NETBSD +# define ASAN_INTERCEPT_PTHREAD_ATFORK 1 +# else +# define ASAN_INTERCEPT_PTHREAD_ATFORK 0 +# endif DECLARE_REAL(int, memcmp, const void *a1, const void *a2, SIZE_T size) DECLARE_REAL(char*, strchr, const char *str, int c) diff --git a/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp b/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp index bdf328f892063..540141e882edf 100644 --- a/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp +++ b/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp @@ -22,6 +22,14 @@ using namespace __asan; +// AIX currently can't retrieve memcpy's address, we have to use internal_memcpy +// here. +#if !SANITIZER_AIX +# define ASAN_MEMCPY_RETURN(to, from, size) REAL(memcpy)(to, from, size) +#else +# define ASAN_MEMCPY_RETURN(to, from, size) internal_memcpy(to, from, size) +#endif + // memcpy is called during __asan_init() from the internals of printf(...). // We do not treat memcpy with to==from as a bug. // See http://llvm.org/bugs/show_bug.cgi?id=11763. @@ -36,7 +44,7 @@ using namespace __asan; } else if (UNLIKELY(!AsanInited())) { \ return internal_memcpy(to, from, size); \ } \ - return REAL(memcpy)(to, from, size); \ + return ASAN_MEMCPY_RETURN(to, from, size); \ } while (0) // memset is called inside Printf. diff --git a/compiler-rt/lib/asan/asan_malloc_linux.cpp b/compiler-rt/lib/asan/asan_malloc_linux.cpp index 3f023d4c2ed0a..ca4885fd95d82 100644 --- a/compiler-rt/lib/asan/asan_malloc_linux.cpp +++ b/compiler-rt/lib/asan/asan_malloc_linux.cpp @@ -15,7 +15,7 @@ #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || \ - SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_HAIKU + SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_HAIKU || SANITIZER_AIX # include "asan_allocator.h" # include "asan_interceptors.h" @@ -61,6 +61,24 @@ INTERCEPTOR(void, cfree, void *ptr) { } #endif // SANITIZER_INTERCEPT_CFREE +# if SANITIZER_AIX +INTERCEPTOR(void *, vec_malloc, uptr size) { + if (DlsymAlloc::Use()) + return DlsymAlloc::Allocate(size); + AsanInitFromRtl(); + GET_STACK_TRACE_MALLOC; + return asan_malloc(size, &stack); +} + +INTERCEPTOR(void *, vec_calloc, uptr nmemb, uptr size) { + if (DlsymAlloc::Use()) + return DlsymAlloc::Callocate(nmemb, size); + AsanInitFromRtl(); + GET_STACK_TRACE_MALLOC; + return asan_calloc(nmemb, size, &stack); +} +# endif + INTERCEPTOR(void*, malloc, uptr size) { if (DlsymAlloc::Use()) return DlsymAlloc::Allocate(size);