Skip to content
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion compiler-rt/lib/asan/asan_allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -770,11 +770,16 @@ 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 does not intercept memcpy, 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;
Expand Down
57 changes: 49 additions & 8 deletions compiler-rt/lib/asan/asan_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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 int *)(thread);
# else
return result ? 0 : *(uptr *)(thread);
# endif
});
}
if (result != 0) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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<char*>(new_mem);
}
Expand All @@ -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<char*>(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);
Expand All @@ -632,6 +654,7 @@ INTERCEPTOR(char*, strncpy, char *to, const char *from, usize size) {
}
return REAL(strncpy)(to, from, size);
}
# endif

template <typename Fn>
static ALWAYS_INLINE auto StrtolImpl(void *ctx, Fn real, const char *nptr,
Expand Down Expand Up @@ -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()))
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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

Expand Down
150 changes: 87 additions & 63 deletions compiler-rt/lib/asan/asan_interceptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,22 @@ void InitializePlatformInterceptors();
// really defined to replace libc functions.
#if !SANITIZER_FUCHSIA

# 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
# 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
Expand All @@ -56,73 +66,87 @@ 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 !SANITIZER_WINDOWS && !SANITIZER_AIX
# define ASAN_INTERCEPT_SIGLONGJMP 1
# else
# define ASAN_INTERCEPT_SIGLONGJMP 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
# 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

# if !SANITIZER_WINDOWS && !SANITIZER_AIX
# define ASAN_INTERCEPT___CXA_ATEXIT 1
# else
# define ASAN_INTERCEPT___CXA_ATEXIT 0
# endif

#if !SANITIZER_WINDOWS
# define ASAN_INTERCEPT___CXA_ATEXIT 1
#else
# define ASAN_INTERCEPT___CXA_ATEXIT 0
#endif
# if SANITIZER_AIX
# define ASAN_INTERCEPT_EXIT 1
# else
# define ASAN_INTERCEPT_EXIT 0
# endif

#if SANITIZER_NETBSD
# define ASAN_INTERCEPT_ATEXIT 1
#else
# define ASAN_INTERCEPT_ATEXIT 0
#endif
# if SANITIZER_NETBSD
# define ASAN_INTERCEPT_ATEXIT 1
# else
# define ASAN_INTERCEPT_ATEXIT 0
# endif

#if SANITIZER_GLIBC
# define ASAN_INTERCEPT___STRDUP 1
#else
# define ASAN_INTERCEPT___STRDUP 0
#endif
# if SANITIZER_GLIBC
# define ASAN_INTERCEPT___STRDUP 1
# else
# define ASAN_INTERCEPT___STRDUP 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 && 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_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_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)
Expand Down
9 changes: 8 additions & 1 deletion compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@

using namespace __asan;

// AIX does not intercept memcpy, so we have to use internal_memcpy.
#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.
Expand All @@ -36,7 +43,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.
Expand Down
Loading
Loading