-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[asan] Implement interception on AIX #131870
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 24 commits
1c2952c
549b134
d3301a3
6ffa232
4890013
dcde670
c254027
878a567
7cc64a1
4159aa9
b0098db
b159f20
67317ad
16a2d81
0935ed2
30d1f12
38a520d
4c8cd38
8ce7b54
fb70384
b024cac
b57eee8
c3ff763
ab72dfa
72b85c9
93a5093
ad0b183
1b40995
b7d52db
cab7b84
18a60b9
0048e02
54f6a42
cb545f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks like a formatting change that should have happened on a separate PR? |
||
| 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<char*>(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<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); | ||
|
|
@@ -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, | ||
|
|
@@ -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 | ||
|
Comment on lines
+804
to
+810
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe split adding new interceptors out to a separate PR and focus this PR on compatibility changes to existing sanitizer code. |
||
|
|
||
| # 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 | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
|
@@ -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 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is special about AIX that we need it for AIX and not other platforms? What happens on AIX if we don't have this? |
||
| # 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) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the logical reason to use
SANITIZER_INTERCEPT_MEMCPYhere asmemcpymeans we cannot useinternal_memcpyin this context, andSANITIZER_INTERCEPT_MEMCPYwas added in d7c6cad, which basically makes it an alias ofSI_NOT_AIX. I believe this should just useSI_NOT_AIXdirectly (with a TODO to remove this function whenREAL(memcpy)is set up to work on AIX).