Skip to content

Commit dcde670

Browse files
committed
Add asan interceptor part
1 parent 4890013 commit dcde670

File tree

5 files changed

+103
-8
lines changed

5 files changed

+103
-8
lines changed

compiler-rt/lib/asan/asan_allocator.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -770,11 +770,16 @@ struct Allocator {
770770
u8 chunk_state = atomic_load(&m->chunk_state, memory_order_acquire);
771771
if (chunk_state != CHUNK_ALLOCATED)
772772
ReportInvalidFree(old_ptr, chunk_state, stack);
773-
CHECK_NE(REAL(memcpy), nullptr);
774773
uptr memcpy_size = Min(new_size, m->UsedSize());
775774
// If realloc() races with free(), we may start copying freed memory.
776775
// However, we will report racy double-free later anyway.
776+
#if !SANITIZER_AIX
777+
CHECK_NE(REAL(memcpy), nullptr);
777778
REAL(memcpy)(new_ptr, old_ptr, memcpy_size);
779+
#else
780+
// AIX does not intercept memcpy, we have to use internal_memcpy here.
781+
internal_memcpy(new_ptr, old_ptr, memcpy_size);
782+
#endif
778783
Deallocate(old_ptr, 0, 0, stack, FROM_MALLOC);
779784
}
780785
return new_ptr;

compiler-rt/lib/asan/asan_interceptors.cpp

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ namespace __asan {
5656
# define ASAN_READ_STRING(ctx, s, n) \
5757
ASAN_READ_STRING_OF_LEN((ctx), (s), internal_strlen(s), (n))
5858

59+
#if SANITIZER_INTERCEPT_STRCAT || SANITIZER_INTERCEPT_STRCPY
5960
static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
6061
#if SANITIZER_INTERCEPT_STRNLEN
6162
if (REAL(strnlen)) {
@@ -64,6 +65,7 @@ static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
6465
#endif
6566
return internal_strnlen(s, maxlen);
6667
}
68+
#endif
6769

6870
void SetThreadName(const char *name) {
6971
AsanThread *t = GetCurrentThread();
@@ -275,7 +277,12 @@ INTERCEPTOR(int, pthread_create, void *thread, void *attr,
275277
# endif
276278
asanThreadArgRetval().Create(detached, {start_routine, arg}, [&]() -> uptr {
277279
result = REAL(pthread_create)(thread, attr, asan_thread_start, t);
280+
// AIX pthread_t is unsigned int.
281+
#if SANITIZER_AIX
282+
return result ? 0 : *(unsigned int *)(thread);
283+
#else
278284
return result ? 0 : *(uptr *)(thread);
285+
#endif
279286
});
280287
}
281288
if (result != 0) {
@@ -432,10 +439,12 @@ INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp,
432439
#define siglongjmp __siglongjmp14
433440
#endif
434441

442+
#if ASAN_INTERCEPT_LONGJMP
435443
INTERCEPTOR(void, longjmp, void *env, int val) {
436444
__asan_handle_no_return();
437445
REAL(longjmp)(env, val);
438446
}
447+
#endif
439448

440449
#if ASAN_INTERCEPT__LONGJMP
441450
INTERCEPTOR(void, _longjmp, void *env, int val) {
@@ -508,6 +517,7 @@ DEFINE_REAL(char*, index, const char *string, int c)
508517

509518
// For both strcat() and strncat() we need to check the validity of |to|
510519
// argument irrespective of the |from| length.
520+
#if SANITIZER_INTERCEPT_STRCAT
511521
INTERCEPTOR(char *, strcat, char *to, const char *from) {
512522
void *ctx;
513523
ASAN_INTERCEPTOR_ENTER(ctx, strcat);
@@ -528,6 +538,7 @@ DEFINE_REAL(char*, index, const char *string, int c)
528538
}
529539
return REAL(strcat)(to, from);
530540
}
541+
#endif
531542

532543
INTERCEPTOR(char*, strncat, char *to, const char *from, usize size) {
533544
void *ctx;
@@ -548,6 +559,7 @@ INTERCEPTOR(char*, strncat, char *to, const char *from, usize size) {
548559
return REAL(strncat)(to, from, size);
549560
}
550561

562+
#if SANITIZER_INTERCEPT_STRCPY
551563
INTERCEPTOR(char *, strcpy, char *to, const char *from) {
552564
void *ctx;
553565
ASAN_INTERCEPTOR_ENTER(ctx, strcpy);
@@ -569,6 +581,7 @@ INTERCEPTOR(char *, strcpy, char *to, const char *from) {
569581
}
570582
return REAL(strcpy)(to, from);
571583
}
584+
#endif
572585

573586
// Windows doesn't always define the strdup identifier,
574587
// and when it does it's a macro defined to either _strdup
@@ -596,9 +609,16 @@ INTERCEPTOR(char*, strdup, const char *s) {
596609
GET_STACK_TRACE_MALLOC;
597610
void *new_mem = asan_malloc(length + 1, &stack);
598611
if (new_mem) {
612+
# if SANITIZER_AIX
613+
// memcpy is a static function defined in libc.a on AIX. It can not be
614+
// intercepted, so REAL(memcpy) is null on AIX. Use internal_memcpy instead.
615+
internal_memcpy(new_mem, s, length + 1);
616+
# else
599617
REAL(memcpy)(new_mem, s, length + 1);
618+
# endif
600619
}
601620
return reinterpret_cast<char*>(new_mem);
621+
602622
}
603623

604624
# if ASAN_INTERCEPT___STRDUP
@@ -614,12 +634,17 @@ INTERCEPTOR(char*, __strdup, const char *s) {
614634
GET_STACK_TRACE_MALLOC;
615635
void *new_mem = asan_malloc(length + 1, &stack);
616636
if (new_mem) {
637+
#if SANITIZER_AIX
638+
internal_memcpy(new_mem, s, length + 1);
639+
#else
617640
REAL(memcpy)(new_mem, s, length + 1);
641+
#endif
618642
}
619643
return reinterpret_cast<char*>(new_mem);
620644
}
621645
#endif // ASAN_INTERCEPT___STRDUP
622646

647+
#if SANITIZER_INTERCEPT_STRCPY
623648
INTERCEPTOR(char*, strncpy, char *to, const char *from, usize size) {
624649
void *ctx;
625650
ASAN_INTERCEPTOR_ENTER(ctx, strncpy);
@@ -632,6 +657,7 @@ INTERCEPTOR(char*, strncpy, char *to, const char *from, usize size) {
632657
}
633658
return REAL(strncpy)(to, from, size);
634659
}
660+
#endif
635661

636662
template <typename Fn>
637663
static ALWAYS_INLINE auto StrtolImpl(void *ctx, Fn real, const char *nptr,
@@ -743,6 +769,14 @@ static void AtCxaAtexit(void *unused) {
743769
}
744770
#endif
745771

772+
#if ASAN_INTERCEPT_EXIT
773+
INTERCEPTOR(void, exit, int status) {
774+
AsanInitFromRtl();
775+
StopInitOrderChecking();
776+
REAL(exit)(status);
777+
}
778+
#endif
779+
746780
#if ASAN_INTERCEPT___CXA_ATEXIT
747781
INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
748782
void *dso_handle) {
@@ -804,10 +838,14 @@ void InitializeAsanInterceptors() {
804838
InitializeSignalInterceptors();
805839

806840
// Intercept str* functions.
841+
#if SANITIZER_INTERCEPT_STRCAT
807842
ASAN_INTERCEPT_FUNC(strcat);
808-
ASAN_INTERCEPT_FUNC(strcpy);
809843
ASAN_INTERCEPT_FUNC(strncat);
844+
#endif
845+
#if SANITIZER_INTERCEPT_STRCPY
846+
ASAN_INTERCEPT_FUNC(strcpy);
810847
ASAN_INTERCEPT_FUNC(strncpy);
848+
#endif
811849
ASAN_INTERCEPT_FUNC(strdup);
812850
# if ASAN_INTERCEPT___STRDUP
813851
ASAN_INTERCEPT_FUNC(__strdup);
@@ -826,8 +864,10 @@ void InitializeAsanInterceptors() {
826864
ASAN_INTERCEPT_FUNC(__isoc23_strtoll);
827865
# endif
828866

829-
// Intecept jump-related functions.
867+
// Intercept jump-related functions.
868+
#if ASAN_INTERCEPT_LONGJMP
830869
ASAN_INTERCEPT_FUNC(longjmp);
870+
#endif
831871

832872
# if ASAN_INTERCEPT_SWAPCONTEXT
833873
ASAN_INTERCEPT_FUNC(swapcontext);
@@ -894,6 +934,10 @@ void InitializeAsanInterceptors() {
894934
ASAN_INTERCEPT_FUNC(atexit);
895935
#endif
896936

937+
#if ASAN_INTERCEPT_EXIT
938+
ASAN_INTERCEPT_FUNC(exit);
939+
#endif
940+
897941
#if ASAN_INTERCEPT_PTHREAD_ATFORK
898942
ASAN_INTERCEPT_FUNC(pthread_atfork);
899943
#endif

compiler-rt/lib/asan/asan_interceptors.h

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,20 @@ void InitializePlatformInterceptors();
3131
// really defined to replace libc functions.
3232
#if !SANITIZER_FUCHSIA
3333

34+
#if !SANITIZER_AIX
35+
# define ASAN_INTERCEPT_LONGJMP 1
36+
#else
37+
# define ASAN_INTERCEPT_LONGJMP 0
38+
#endif
39+
3440
// Use macro to describe if specific function should be
3541
// intercepted on a given platform.
3642
#if !SANITIZER_WINDOWS
43+
#if !SANITIZER_AIX
3744
# define ASAN_INTERCEPT__LONGJMP 1
45+
#else
46+
# define ASAN_INTERCEPT__LONGJMP 0
47+
#endif
3848
# define ASAN_INTERCEPT_INDEX 1
3949
# define ASAN_INTERCEPT_PTHREAD_CREATE 1
4050
#else
@@ -56,7 +66,7 @@ void InitializePlatformInterceptors();
5666
# define ASAN_INTERCEPT_SWAPCONTEXT 0
5767
#endif
5868

59-
#if !SANITIZER_WINDOWS
69+
#if !SANITIZER_WINDOWS && !SANITIZER_AIX
6070
# define ASAN_INTERCEPT_SIGLONGJMP 1
6171
#else
6272
# define ASAN_INTERCEPT_SIGLONGJMP 0
@@ -84,12 +94,18 @@ void InitializePlatformInterceptors();
8494
# define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 0
8595
#endif
8696

87-
#if !SANITIZER_WINDOWS
97+
#if !SANITIZER_WINDOWS && !SANITIZER_AIX
8898
# define ASAN_INTERCEPT___CXA_ATEXIT 1
8999
#else
90100
# define ASAN_INTERCEPT___CXA_ATEXIT 0
91101
#endif
92102

103+
#if SANITIZER_AIX
104+
# define ASAN_INTERCEPT_EXIT 1
105+
#else
106+
# define ASAN_INTERCEPT_EXIT 0
107+
#endif
108+
93109
#if SANITIZER_NETBSD
94110
# define ASAN_INTERCEPT_ATEXIT 1
95111
#else
@@ -110,14 +126,23 @@ void InitializePlatformInterceptors();
110126
# define ASAN_INTERCEPT_TRYJOIN 0
111127
#endif
112128

129+
#if SANITIZER_AIX
130+
#define SANITIZER_INTERCEPT_STRCAT 0
131+
#define SANITIZER_INTERCEPT_STRCPY 0
132+
#else
133+
#define SANITIZER_INTERCEPT_STRCAT 1
134+
#define SANITIZER_INTERCEPT_STRCPY 1
135+
#endif
136+
137+
113138
#if SANITIZER_LINUX && \
114139
(defined(__arm__) || defined(__aarch64__) || defined(__i386__) || \
115140
defined(__x86_64__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64)
116141
# define ASAN_INTERCEPT_VFORK 1
117142
#else
118143
# define ASAN_INTERCEPT_VFORK 0
119144
#endif
120-
145+
`
121146
#if SANITIZER_NETBSD
122147
# define ASAN_INTERCEPT_PTHREAD_ATFORK 1
123148
#else

compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ using namespace __asan;
2525
// memcpy is called during __asan_init() from the internals of printf(...).
2626
// We do not treat memcpy with to==from as a bug.
2727
// See http://llvm.org/bugs/show_bug.cgi?id=11763.
28+
// AIX does not intercept memcpy, so we have to use internal_memcpy.
2829
#define ASAN_MEMCPY_IMPL(ctx, to, from, size) \
2930
do { \
3031
if (LIKELY(replace_intrin_cached)) { \
@@ -36,7 +37,8 @@ using namespace __asan;
3637
} else if (UNLIKELY(!AsanInited())) { \
3738
return internal_memcpy(to, from, size); \
3839
} \
39-
return REAL(memcpy)(to, from, size); \
40+
return SANITIZER_AIX ? internal_memcpy(to, from, size) : \
41+
REAL(memcpy)(to, from, size); \
4042
} while (0)
4143

4244
// memset is called inside Printf.

compiler-rt/lib/asan/asan_malloc_linux.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
//===----------------------------------------------------------------------===//
1515

1616
#include "sanitizer_common/sanitizer_platform.h"
17+
// FIXME: rename this file, this is not just for Linux now, see FUCHSIA and AIX.
1718
#if SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || \
18-
SANITIZER_NETBSD || SANITIZER_SOLARIS
19+
SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_AIX
1920

2021
# include "asan_allocator.h"
2122
# include "asan_interceptors.h"
@@ -61,6 +62,24 @@ INTERCEPTOR(void, cfree, void *ptr) {
6162
}
6263
#endif // SANITIZER_INTERCEPT_CFREE
6364

65+
#if SANITIZER_AIX
66+
INTERCEPTOR(void*, vec_malloc, uptr size) {
67+
if (DlsymAlloc::Use())
68+
return DlsymAlloc::Allocate(size);
69+
AsanInitFromRtl();
70+
GET_STACK_TRACE_MALLOC;
71+
return asan_malloc(size, &stack);
72+
}
73+
74+
INTERCEPTOR(void*, vec_calloc, uptr nmemb, uptr size) {
75+
if (DlsymAlloc::Use())
76+
return DlsymAlloc::Callocate(nmemb, size);
77+
AsanInitFromRtl();
78+
GET_STACK_TRACE_MALLOC;
79+
return asan_calloc(nmemb, size, &stack);
80+
}
81+
#endif
82+
6483
INTERCEPTOR(void*, malloc, uptr size) {
6584
if (DlsymAlloc::Use())
6685
return DlsymAlloc::Allocate(size);

0 commit comments

Comments
 (0)