Skip to content

[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

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open

Conversation

jakeegan
Copy link
Member

@jakeegan jakeegan commented Mar 18, 2025

Adjust asan interceptor support for AIX.

Issue: #138916

Copy link

github-actions bot commented Mar 18, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@jakeegan jakeegan changed the title [sanitizer_common] Implement interceptors for AIX [sanitizer_common] Implement address sanitizer on AIX: interceptors (5/n) Mar 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 24, 2025

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Jake Egan (jakeegan)

Changes

Builds on the effort to support AIX in sanitizer_common/asan. Intercepting functions in shared libraries is not supported on AIX yet.

Previous PR: #131868


Patch is 20.14 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/131870.diff

9 Files Affected:

  • (modified) compiler-rt/lib/interception/CMakeLists.txt (+2)
  • (modified) compiler-rt/lib/interception/interception.h (+17-2)
  • (added) compiler-rt/lib/interception/interception_aix.cpp (+45)
  • (added) compiler-rt/lib/interception/interception_aix.h (+36)
  • (modified) compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc (+42-12)
  • (modified) compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc (+2)
  • (modified) compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc (+2)
  • (modified) compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h (+33-19)
  • (modified) compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h (+1-1)
diff --git a/compiler-rt/lib/interception/CMakeLists.txt b/compiler-rt/lib/interception/CMakeLists.txt
index fe7fa27fbc78b..57c8c8ba20141 100644
--- a/compiler-rt/lib/interception/CMakeLists.txt
+++ b/compiler-rt/lib/interception/CMakeLists.txt
@@ -1,6 +1,7 @@
 # Build for the runtime interception helper library.
 
 set(INTERCEPTION_SOURCES
+  interception_aix.cpp
   interception_linux.cpp
   interception_mac.cpp
   interception_win.cpp
@@ -9,6 +10,7 @@ set(INTERCEPTION_SOURCES
 
 set(INTERCEPTION_HEADERS
   interception.h
+  interception_aix.h
   interception_linux.h
   interception_mac.h
   interception_win.h
diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h
index 3cb6b446638e0..3a20cfb04dcd6 100644
--- a/compiler-rt/lib/interception/interception.h
+++ b/compiler-rt/lib/interception/interception.h
@@ -19,7 +19,7 @@
 
 #if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_APPLE &&    \
     !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \
-    !SANITIZER_SOLARIS
+    !SANITIZER_SOLARIS && !SANITIZER_AIX
 #  error "Interception doesn't work on this operating system."
 #endif
 
@@ -168,6 +168,16 @@ const interpose_substitution substitution_##func_name[]             \
     extern "C" ret_type func(__VA_ARGS__);
 # define DECLARE_WRAPPER_WINAPI(ret_type, func, ...)  \
     extern "C" __declspec(dllimport) ret_type __stdcall func(__VA_ARGS__);
+#elif SANITIZER_AIX
+#  define WRAP(x) __interceptor_##x
+#  define TRAMPOLINE(x) WRAP(x)
+// # define WRAPPER_NAME(x) "__interceptor_" #x
+#  define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
+// AIX's linker will not select the weak symbol, so don't use weak for the
+// interceptors.
+#  define DECLARE_WRAPPER(ret_type, func, ...) \
+    extern "C" ret_type func(__VA_ARGS__)      \
+        __attribute__((alias("__interceptor_" #func), visibility("default")));
 #elif !SANITIZER_FUCHSIA  // LINUX, FREEBSD, NETBSD, SOLARIS
 # define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
 # if ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT
@@ -367,7 +377,12 @@ inline void DoesNotSupportStaticLinking() {}
 
 #define INCLUDED_FROM_INTERCEPTION_LIB
 
-#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
+#if SANITIZER_AIX
+# include "interception_aix.h"
+# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_AIX(func)
+# define INTERCEPT_FUNCTION_VER(func, symver) INTERCEPT_FUNCTION_AIX(func)
+
+#elif SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
     SANITIZER_SOLARIS
 
 # include "interception_linux.h"
diff --git a/compiler-rt/lib/interception/interception_aix.cpp b/compiler-rt/lib/interception/interception_aix.cpp
new file mode 100644
index 0000000000000..953bbad96eb47
--- /dev/null
+++ b/compiler-rt/lib/interception/interception_aix.cpp
@@ -0,0 +1,45 @@
+//===-- interception_aix.cpp ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// AIX-specific interception methods.
+//===----------------------------------------------------------------------===//
+
+#include "interception.h"
+#include "sanitizer_common/sanitizer_common.h"
+
+#if SANITIZER_AIX
+
+#  include <dlfcn.h>  // for dlsym()
+
+namespace __interception {
+
+static void *GetFuncAddr(const char *name, uptr wrapper_addr) {
+  // AIX dlsym can only defect the functions that are exported, so
+  // on AIX, we can not intercept some basic functions like memcpy.
+  // FIXME: if we are going to ship dynamic asan library, we may need to search
+  // all the loaded modules with RTLD_DEFAULT if RTLD_NEXT failed.
+  void *addr = dlsym(RTLD_NEXT, name);
+
+  // In case `name' is not loaded, dlsym ends up finding the actual wrapper.
+  // We don't want to intercept the wrapper and have it point to itself.
+  if ((uptr)addr == wrapper_addr)
+    addr = nullptr;
+  return addr;
+}
+
+bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
+                       uptr wrapper) {
+  void *addr = GetFuncAddr(name, wrapper);
+  *ptr_to_real = (uptr)addr;
+  return addr && (func == wrapper);
+}
+
+}  // namespace __interception
+#endif  // SANITIZER_AIX
diff --git a/compiler-rt/lib/interception/interception_aix.h b/compiler-rt/lib/interception/interception_aix.h
new file mode 100644
index 0000000000000..08d17caeb6a8d
--- /dev/null
+++ b/compiler-rt/lib/interception/interception_aix.h
@@ -0,0 +1,36 @@
+//===-- interception_aix.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// AIX-specific interception methods.
+//===----------------------------------------------------------------------===//
+
+#if SANITIZER_AIX
+
+#  if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
+#    error \
+        "interception_aix.h should be included from interception library only"
+#  endif
+
+#  ifndef INTERCEPTION_AIX_H
+#    define INTERCEPTION_AIX_H
+
+namespace __interception {
+bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
+                       uptr wrapper);
+}  // namespace __interception
+
+#    define INTERCEPT_FUNCTION_AIX(func)                \
+      ::__interception::InterceptFunction(              \
+          #func, (::__interception::uptr *)&REAL(func), \
+          (::__interception::uptr) & (func),            \
+          (::__interception::uptr)&WRAP(func))
+
+#  endif  // INTERCEPTION_AIX_H
+#endif    // SANITIZER_AIX
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 24a8a2d4dc55b..35876084f8107 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -480,7 +480,7 @@ INTERCEPTOR(char*, textdomain, const char *domainname) {
 #define INIT_TEXTDOMAIN
 #endif
 
-#if SANITIZER_INTERCEPT_STRCMP || SANITIZER_INTERCEPT_MEMCMP
+#if SANITIZER_INTERCEPT_MEMCMP
 static inline int CharCmpX(unsigned char c1, unsigned char c2) {
   return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
 }
@@ -953,7 +953,7 @@ INTERCEPTOR(double, frexp, double x, int *exp) {
 #define INIT_FREXP
 #endif  // SANITIZER_INTERCEPT_FREXP
 
-#if SANITIZER_INTERCEPT_FREXPF_FREXPL
+#if SANITIZER_INTERCEPT_FREXPF
 INTERCEPTOR(float, frexpf, float x, int *exp) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
@@ -963,6 +963,12 @@ INTERCEPTOR(float, frexpf, float x, int *exp) {
   return res;
 }
 
+#define INIT_FREXPF COMMON_INTERCEPT_FUNCTION(frexpf);
+#else
+#define INIT_FREXPF
+#endif
+
+#if SANITIZER_INTERCEPT_FREXPL
 INTERCEPTOR(long double, frexpl, long double x, int *exp) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
@@ -972,12 +978,10 @@ INTERCEPTOR(long double, frexpl, long double x, int *exp) {
   return res;
 }
 
-#define INIT_FREXPF_FREXPL           \
-  COMMON_INTERCEPT_FUNCTION(frexpf); \
-  COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
+#define INIT_FREXPL COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
 #else
-#define INIT_FREXPF_FREXPL
-#endif  // SANITIZER_INTERCEPT_FREXPF_FREXPL
+#define INIT_FREXPL
+#endif
 
 #if SI_POSIX
 static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
@@ -1346,7 +1350,8 @@ INTERCEPTOR(unsigned long, time, unsigned long *t) {
 #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
 static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
-#if !SANITIZER_SOLARIS
+// AIX tm struct does not have tm_zone field.
+#if !SANITIZER_SOLARIS && !SANITIZER_AIX
   if (tm->tm_zone) {
     // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
     // can point to shared memory and tsan would report a data race.
@@ -1731,8 +1736,10 @@ INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to,
 VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
 #endif
 
+#if SANITIZER_INTERCEPT_VASPRINTF
 INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
 VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
+#endif
 
 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
 INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
@@ -1783,8 +1790,10 @@ INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag,
 FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format)
 #endif
 
+#if SANITIZER_INTERCEPT_ASPRINTF
 INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
 FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
+#endif
 
 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
 INTERCEPTOR(int, __isoc99_printf, const char *format, ...)
@@ -1807,17 +1816,29 @@ FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
 #endif  // SANITIZER_INTERCEPT_PRINTF
 
 #if SANITIZER_INTERCEPT_PRINTF
+#if SANITIZER_AIX
+#define INIT_PRINTF                     \
+  COMMON_INTERCEPT_FUNCTION_LDBL(printf);    \
+  COMMON_INTERCEPT_FUNCTION_LDBL(sprintf);   \
+  COMMON_INTERCEPT_FUNCTION_LDBL(snprintf);  \
+  COMMON_INTERCEPT_FUNCTION_LDBL(fprintf);   \
+  COMMON_INTERCEPT_FUNCTION_LDBL(vprintf);   \
+  COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf);  \
+  COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \
+  COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);
+#else
 #define INIT_PRINTF                     \
   COMMON_INTERCEPT_FUNCTION_LDBL(printf);    \
   COMMON_INTERCEPT_FUNCTION_LDBL(sprintf);   \
   COMMON_INTERCEPT_FUNCTION_LDBL(snprintf);  \
-  COMMON_INTERCEPT_FUNCTION_LDBL(asprintf);  \
   COMMON_INTERCEPT_FUNCTION_LDBL(fprintf);   \
   COMMON_INTERCEPT_FUNCTION_LDBL(vprintf);   \
   COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf);  \
   COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \
+  COMMON_INTERCEPT_FUNCTION_LDBL(asprintf);  \
   COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf); \
   COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);
+#endif
 #else
 #define INIT_PRINTF
 #endif
@@ -3901,7 +3922,11 @@ INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
   if (res != ((SIZE_T)-1)) {
     CHECK_LE(res, sizeof(local_dest));
     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
-    REAL(memcpy)(dest, local_dest, res);
+#if !SANITIZER_AIX
+      REAL(memcpy)(dest, local_dest, res);
+#else
+      internal_memcpy(dest, local_dest, res);
+#endif
   }
   return res;
 }
@@ -3923,7 +3948,11 @@ INTERCEPTOR(int, wctomb, char *dest, wchar_t src) {
   if (res != -1) {
     CHECK_LE(res, sizeof(local_dest));
     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
-    REAL(memcpy)(dest, local_dest, res);
+#if !SANITIZER_AIX
+      REAL(memcpy)(dest, local_dest, res);
+#else
+      internal_memcpy(dest, local_dest, res);
+#endif
   }
   return res;
 }
@@ -10329,7 +10358,8 @@ static void InitializeCommonInterceptors() {
   INIT_PRINTF_L;
   INIT_ISOC99_PRINTF;
   INIT_FREXP;
-  INIT_FREXPF_FREXPL;
+  INIT_FREXPF;
+  INIT_FREXPL;
   INIT_GETPWNAM_AND_FRIENDS;
   INIT_GETPWNAM_R_AND_FRIENDS;
   INIT_GETPWENT;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
index 49ec4097c900b..5b23039954a43 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
@@ -73,7 +73,9 @@ static void ioctl_table_fill() {
   _(TIOCNXCL, NONE, 0);
   _(TIOCOUTQ, WRITE, sizeof(int));
   _(TIOCPKT, READ, sizeof(int));
+#if !SANITIZER_AIX
   _(TIOCSCTTY, NONE, 0);
+#endif
   _(TIOCSETD, READ, sizeof(int));
   _(TIOCSPGRP, READ, pid_t_sz);
   _(TIOCSTI, READ, sizeof(char));
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc
index 1565a494140f6..e542a6c7b438a 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc
@@ -36,6 +36,8 @@
 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
 #elif SANITIZER_WINDOWS64
 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
+#elif SANITIZER_AIX
+#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
 #else
 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 1
 #endif  // SANITIZER_APPLE
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index febd233bb1e3c..43a37037c971d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -139,6 +139,12 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SI_SOLARIS 0
 #endif
 
+#if SANITIZER_AIX
+#define SI_NOT_AIX 0
+#else
+#define SI_NOT_AIX 1
+#endif
+
 #if SANITIZER_SOLARIS32
 #define SI_SOLARIS32 1
 #else
@@ -159,20 +165,20 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 
 #define SANITIZER_INTERCEPT_STRLEN SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_STRNLEN (SI_NOT_MAC && SI_NOT_FUCHSIA)
-#define SANITIZER_INTERCEPT_STRCMP SI_NOT_FUCHSIA
+#define SANITIZER_INTERCEPT_STRCMP (SI_NOT_FUCHSIA && SI_NOT_AIX)
 #define SANITIZER_INTERCEPT_STRSTR SI_NOT_FUCHSIA
-#define SANITIZER_INTERCEPT_STRCASESTR SI_POSIX
+#define SANITIZER_INTERCEPT_STRCASESTR (SI_POSIX && SI_NOT_AIX)
 #define SANITIZER_INTERCEPT_STRTOK SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_STRCHR SI_NOT_FUCHSIA
-#define SANITIZER_INTERCEPT_STRCHRNUL SI_POSIX_NOT_MAC
+#define SANITIZER_INTERCEPT_STRCHRNUL (SI_POSIX_NOT_MAC && SI_NOT_AIX)
 #define SANITIZER_INTERCEPT_STRRCHR SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_STRSPN SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_STRPBRK SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID || SI_SOLARIS
 #define SANITIZER_INTERCEPT_STRCASECMP SI_POSIX
 #define SANITIZER_INTERCEPT_MEMSET 1
-#define SANITIZER_INTERCEPT_MEMMOVE 1
-#define SANITIZER_INTERCEPT_MEMCPY 1
+#define SANITIZER_INTERCEPT_MEMMOVE SI_NOT_AIX
+#define SANITIZER_INTERCEPT_MEMCPY SI_NOT_AIX
 #define SANITIZER_INTERCEPT_MEMCMP SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_BCMP \
   SANITIZER_INTERCEPT_MEMCMP &&  \
@@ -231,6 +237,8 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT_ISOC99_SCANF SI_GLIBC
 
 #ifndef SANITIZER_INTERCEPT_PRINTF
+#define SANITIZER_INTERCEPT_ASPRINTF SI_NOT_AIX
+#define SANITIZER_INTERCEPT_VASPRINTF SI_NOT_AIX
 #define SANITIZER_INTERCEPT_PRINTF SI_POSIX
 #define SANITIZER_INTERCEPT_PRINTF_L (SI_FREEBSD || SI_NETBSD)
 #define SANITIZER_INTERCEPT_ISOC99_PRINTF SI_GLIBC
@@ -239,8 +247,10 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT___PRINTF_CHK \
   (SANITIZER_INTERCEPT_PRINTF && SI_GLIBC)
 
-#define SANITIZER_INTERCEPT_FREXP SI_NOT_FUCHSIA
-#define SANITIZER_INTERCEPT_FREXPF_FREXPL SI_POSIX
+// AIX libc does not export FREXP and FREXP.
+#define SANITIZER_INTERCEPT_FREXP (SI_NOT_FUCHSIA && SI_NOT_AIX)
+#define SANITIZER_INTERCEPT_FREXPF (SI_POSIX && SI_NOT_AIX)
+#define SANITIZER_INTERCEPT_FREXPL SI_POSIX
 
 #define SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS SI_POSIX
 #define SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS \
@@ -289,7 +299,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT_ACCEPT4 \
   (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_FREEBSD)
 #define SANITIZER_INTERCEPT_PACCEPT SI_NETBSD
-#define SANITIZER_INTERCEPT_MODF SI_POSIX
+#define SANITIZER_INTERCEPT_MODF (SI_POSIX && SI_NOT_AIX)
 #define SANITIZER_INTERCEPT_RECVMSG SI_POSIX
 #define SANITIZER_INTERCEPT_SENDMSG SI_POSIX
 #define SANITIZER_INTERCEPT_RECVMMSG SI_LINUX
@@ -324,8 +334,9 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT___WCSXFRM_L SI_LINUX
 #define SANITIZER_INTERCEPT_WCSNRTOMBS \
   (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
-#define SANITIZER_INTERCEPT_WCRTOMB \
-  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_WCRTOMB                                           \
+  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS || \
+   !SI_NOT_AIX)
 #define SANITIZER_INTERCEPT_WCTOMB \
   (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID || SI_SOLARIS
@@ -365,7 +376,8 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_STATFS \
   (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
-#define SANITIZER_INTERCEPT_STATFS64 SI_GLIBC && SANITIZER_HAS_STATFS64
+#define SANITIZER_INTERCEPT_STATFS64 \
+  ((SI_GLIBC || !SI_NOT_AIX) && SANITIZER_HAS_STATFS64)
 #define SANITIZER_INTERCEPT_STATVFS \
   (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID)
 #define SANITIZER_INTERCEPT_STATVFS64 SI_GLIBC
@@ -414,10 +426,10 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT_TTYNAME_R SI_POSIX
 #define SANITIZER_INTERCEPT_TEMPNAM SI_POSIX
 #define SANITIZER_INTERCEPT_SINCOS SI_LINUX || SI_SOLARIS
-#define SANITIZER_INTERCEPT_REMQUO SI_POSIX
-#define SANITIZER_INTERCEPT_REMQUOL (SI_POSIX && !SI_NETBSD)
-#define SANITIZER_INTERCEPT_LGAMMA SI_POSIX
-#define SANITIZER_INTERCEPT_LGAMMAL (SI_POSIX && !SI_NETBSD)
+#define SANITIZER_INTERCEPT_REMQUO (SI_POSIX && SI_NOT_AIX)
+#define SANITIZER_INTERCEPT_REMQUOL (SI_POSIX && !SI_NETBSD && SI_NOT_AIX)
+#define SANITIZER_INTERCEPT_LGAMMA (SI_POSIX && SI_NOT_AIX)
+#define SANITIZER_INTERCEPT_LGAMMAL (SI_POSIX && !SI_NETBSD && SI_NOT_AIX)
 #define SANITIZER_INTERCEPT_LGAMMA_R (SI_FREEBSD || SI_LINUX || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID || SI_SOLARIS
 #define SANITIZER_INTERCEPT_DRAND48_R SI_GLIBC
@@ -502,9 +514,11 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SI_STAT_LINUX (SI_LINUX && __GLIBC_PREREQ(2, 33))
 #define SANITIZER_INTERCEPT_STAT                                        \
   (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS ||     \
-   SI_STAT_LINUX)
-#define SANITIZER_INTERCEPT_STAT64 SI_STAT_LINUX && SANITIZER_HAS_STAT64
-#define SANITIZER_INTERCEPT_LSTAT (SI_NETBSD || SI_FREEBSD || SI_STAT_LINUX)
+   SI_STAT_LINUX || !SI_NOT_AIX)
+#define SANITIZER_INTERCEPT_STAT64 \
+  ((SI_STAT_LINUX || !SI_NOT_AIX) && SANITIZER_HAS_STAT64)
+#define SANITIZER_INTERCEPT_LSTAT \
+  (SI_NETBSD || SI_FREEBSD || SI_STAT_LINUX || !SI_NOT_AIX)
 #define SANITIZER_INTERCEPT___XSTAT \
   ((!SANITIZER_INTERCEPT_STAT && SI_POSIX) || SI_STAT_LINUX)
 #define SANITIZER_INTERCEPT___XSTAT64 SI_GLIBC
@@ -572,7 +586,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT_PROTOENT_R SI_GLIBC
 #define SANITIZER_INTERCEPT_NETENT (SI_LINUX || SI_NETBSD || SI_FREEBSD)
 #define SANITIZER_INTERCEPT_SETVBUF \
-  (SI_NETBSD || SI_FREEBSD || SI_LINUX || SI_MAC)
+  (SI_NETBSD || SI_FREEBSD || SI_LINUX || SI_MAC || !SI_NOT_AIX)
 #define SANITIZER_INTERCEPT_GETMNTINFO (SI_NETBSD || SI_FREEBSD || SI_MAC)
 #define SANITIZER_INTERCEPT_MI_VECTOR_HASH SI_NETBSD
 #define SANITIZER_INTERCEPT_GETVFSSTAT SI_NETBSD
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h b/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h
index 41e0613d6fc13..bda0f04687693 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h
@@ -15,7 +15,7 @@
 #    define SANITIZER_REDEFINE_BUILTINS_H
 
 // The asm hack only works...
[truncated]

@jakeegan jakeegan requested a review from mandlebug March 24, 2025 17:42
@llvmbot llvmbot added the compiler-rt:asan Address sanitizer label Apr 24, 2025
@jakeegan jakeegan changed the title [sanitizer_common] Implement address sanitizer on AIX: interceptors (5/n) [sanitizer_common][asan] Implement address sanitizer on AIX: interceptors (5/n) Apr 24, 2025
@jakeegan jakeegan changed the title [sanitizer_common][asan] Implement address sanitizer on AIX: interceptors (5/n) [sanitizer_common][asan] Implement address sanitizer on AIX: interceptors (5/6) Apr 29, 2025
@@ -596,7 +609,13 @@ INTERCEPTOR(char*, strdup, const char *s) {
GET_STACK_TRACE_MALLOC;
void *new_mem = asan_malloc(length + 1, &stack);
if (new_mem) {
# if SANITIZER_AIX
// memcpy is a static function defined in libc.a on AIX. It can not be
// intercepted, so REAL(memcpy) is null on AIX. Use internal_memcpy instead.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please extract inline internal_or_real_memcpy() in the top of the file?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#if SANITIZER_INTERCEPT_MEMCPY rather than SANITIZER_AIX?

@@ -56,6 +56,7 @@ namespace __asan {
# define ASAN_READ_STRING(ctx, s, n) \
ASAN_READ_STRING_OF_LEN((ctx), (s), internal_strlen(s), (n))

# if SANITIZER_INTERCEPT_STRCAT || SANITIZER_INTERCEPT_STRCPY
static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use [[maybe_unused]] instead of #if

@@ -480,7 +480,7 @@ INTERCEPTOR(char*, textdomain, const char *domainname) {
#define INIT_TEXTDOMAIN
#endif

#if SANITIZER_INTERCEPT_STRCMP || SANITIZER_INTERCEPT_MEMCMP
#if SANITIZER_INTERCEPT_MEMCMP
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[[maybe_unused]] instead of #if?

@@ -1807,17 +1816,29 @@ FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
#endif // SANITIZER_INTERCEPT_PRINTF

#if SANITIZER_INTERCEPT_PRINTF
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe something like:

#if SANITIZER_INTERCEPT_PRINTF
#    define INIT_PRINTF_COMMON                          \
      COMMON_INTERCEPT_FUNCTION_LDBL(printf);    \
      COMMON_INTERCEPT_FUNCTION_LDBL(sprintf);   \
      COMMON_INTERCEPT_FUNCTION_LDBL(snprintf);  \
      COMMON_INTERCEPT_FUNCTION_LDBL(fprintf);   \
      COMMON_INTERCEPT_FUNCTION_LDBL(vprintf);   \
      COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf);  \
      COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \
      COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);
#  if !SANITIZER_AIX
#    define INIT_PRINTF_EXTRA                          \
      COMMON_INTERCEPT_FUNCTION_LDBL(asprintf);  \
      COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf); \
#else
   #define INIT_PRINTF_EXTRA                          
#endif
#    define INIT_PRINTF  INIT_PRINTF_COMMON INIT_PRINTF_EXTRA
#  endif
#else
#define INIT_PRINTF
#endif

@jakeegan jakeegan changed the title [sanitizer_common][asan] Implement address sanitizer on AIX: interceptors (5/6) [asan] Implement address sanitizer on AIX: interceptors (5/6) May 6, 2025
@jakeegan
Copy link
Member Author

jakeegan commented May 6, 2025

Split part of the PR to:
#138606
#138608

Still have to address some comments.

@jakeegan jakeegan changed the title [asan] Implement address sanitizer on AIX: interceptors (5/6) [asan] Implement interception on AIX (1/3) May 7, 2025
@jakeegan jakeegan changed the title [asan] Implement interception on AIX (1/3) [asan] Implement interception on AIX May 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants