Skip to content

Conversation

thurstond
Copy link
Contributor

Reverts #160493 due to buildbot failures e.g., #160493 (comment)

The fix-forward (#161624) still had failures on Darwin, and was reverted in #162001 i.e., this pull request completes the revert to green.

@llvmbot
Copy link
Member

llvmbot commented Oct 5, 2025

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

Author: Thurston Dang (thurstond)

Changes

Reverts llvm/llvm-project#160493 due to buildbot failures e.g., #160493 (comment)

The fix-forward (#161624) still had failures on Darwin, and was reverted in #162001 i.e., this pull request completes the revert to green.


Full diff: https://github.com/llvm/llvm-project/pull/162021.diff

8 Files Affected:

  • (modified) compiler-rt/lib/asan/asan_interceptors.cpp (+3-43)
  • (modified) compiler-rt/lib/asan/asan_interceptors.h (-1)
  • (modified) compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp (-4)
  • (modified) compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h (+1-1)
  • (removed) compiler-rt/test/asan/TestCases/wcscat.cpp (-26)
  • (removed) compiler-rt/test/asan/TestCases/wcscpy.cpp (-23)
  • (removed) compiler-rt/test/asan/TestCases/wcsncat.cpp (-27)
  • (removed) compiler-rt/test/asan/TestCases/wcsncpy.cpp (-25)
diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp
index 0f613f0fdc30b..7c9a08b9083a2 100644
--- a/compiler-rt/lib/asan/asan_interceptors.cpp
+++ b/compiler-rt/lib/asan/asan_interceptors.cpp
@@ -58,20 +58,13 @@ namespace __asan {
 
 static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
 #if SANITIZER_INTERCEPT_STRNLEN
-  if (REAL(strnlen))
+  if (REAL(strnlen)) {
     return REAL(strnlen)(s, maxlen);
-#  endif
+  }
+#endif
   return internal_strnlen(s, maxlen);
 }
 
-static inline uptr MaybeRealWcsnlen(const wchar_t* s, uptr maxlen) {
-#  if SANITIZER_INTERCEPT_WCSNLEN
-  if (REAL(wcsnlen))
-    return REAL(wcsnlen)(s, maxlen);
-#  endif
-  return internal_wcsnlen(s, maxlen);
-}
-
 void SetThreadName(const char *name) {
   AsanThread *t = GetCurrentThread();
   if (t)
@@ -577,20 +570,6 @@ INTERCEPTOR(char *, strcpy, char *to, const char *from) {
   return REAL(strcpy)(to, from);
 }
 
-INTERCEPTOR(wchar_t*, wcscpy, wchar_t* to, const wchar_t* from) {
-  void* ctx;
-  ASAN_INTERCEPTOR_ENTER(ctx, wcscpy);
-  if (!TryAsanInitFromRtl())
-    return REAL(wcscpy)(to, from);
-  if (flags()->replace_str) {
-    uptr size = (internal_wcslen(from) + 1) * sizeof(wchar_t);
-    CHECK_RANGES_OVERLAP("wcscpy", to, size, from, size);
-    ASAN_READ_RANGE(ctx, from, size);
-    ASAN_WRITE_RANGE(ctx, to, size);
-  }
-  return REAL(wcscpy)(to, from);
-}
-
 // Windows doesn't always define the strdup identifier,
 // and when it does it's a macro defined to either _strdup
 // or _strdup_dbg, _strdup_dbg ends up calling _strdup, so
@@ -654,20 +633,6 @@ INTERCEPTOR(char*, strncpy, char *to, const char *from, usize size) {
   return REAL(strncpy)(to, from, size);
 }
 
-INTERCEPTOR(wchar_t*, wcsncpy, wchar_t* to, const wchar_t* from, uptr size) {
-  void* ctx;
-  ASAN_INTERCEPTOR_ENTER(ctx, wcsncpy);
-  AsanInitFromRtl();
-  if (flags()->replace_str) {
-    uptr from_size =
-        Min(size, MaybeRealWcsnlen(from, size) + 1) * sizeof(wchar_t);
-    CHECK_RANGES_OVERLAP("wcsncpy", to, from_size, from, from_size);
-    ASAN_READ_RANGE(ctx, from, from_size);
-    ASAN_WRITE_RANGE(ctx, to, size * sizeof(wchar_t));
-  }
-  return REAL(wcsncpy)(to, from, size);
-}
-
 template <typename Fn>
 static ALWAYS_INLINE auto StrtolImpl(void *ctx, Fn real, const char *nptr,
                                      char **endptr, int base)
@@ -844,11 +809,6 @@ void InitializeAsanInterceptors() {
   ASAN_INTERCEPT_FUNC(strncat);
   ASAN_INTERCEPT_FUNC(strncpy);
   ASAN_INTERCEPT_FUNC(strdup);
-
-  // Intercept wcs* functions.
-  ASAN_INTERCEPT_FUNC(wcscpy);
-  ASAN_INTERCEPT_FUNC(wcsncpy);
-
 #  if ASAN_INTERCEPT___STRDUP
   ASAN_INTERCEPT_FUNC(__strdup);
 #endif
diff --git a/compiler-rt/lib/asan/asan_interceptors.h b/compiler-rt/lib/asan/asan_interceptors.h
index 2d551cfafd1f5..3e2386eaf8092 100644
--- a/compiler-rt/lib/asan/asan_interceptors.h
+++ b/compiler-rt/lib/asan/asan_interceptors.h
@@ -129,7 +129,6 @@ DECLARE_REAL(char*, strchr, const char *str, int c)
 DECLARE_REAL(SIZE_T, strlen, const char *s)
 DECLARE_REAL(char*, strncpy, char *to, const char *from, SIZE_T size)
 DECLARE_REAL(SIZE_T, strnlen, const char *s, SIZE_T maxlen)
-DECLARE_REAL(SIZE_T, wcsnlen, const wchar_t* s, SIZE_T maxlen)
 DECLARE_REAL(char*, strstr, const char *s1, const char *s2)
 
 #  if !SANITIZER_APPLE
diff --git a/compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp b/compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp
index 46e0e90738f24..4a69b66574039 100644
--- a/compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp
+++ b/compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp
@@ -63,10 +63,6 @@ INTERCEPT_LIBRARY_FUNCTION_ASAN(strpbrk);
 INTERCEPT_LIBRARY_FUNCTION_ASAN(strspn);
 INTERCEPT_LIBRARY_FUNCTION_ASAN(strstr);
 INTERCEPT_LIBRARY_FUNCTION_ASAN(strtok);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(wcscat);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(wcscpy);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(wcsncat);
-INTERCEPT_LIBRARY_FUNCTION_ASAN(wcsncpy);
 INTERCEPT_LIBRARY_FUNCTION_ASAN(wcslen);
 INTERCEPT_LIBRARY_FUNCTION_ASAN(wcsnlen);
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 88ecd7e16306a..29987decdff45 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -551,7 +551,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC && !SI_NETBSD)
 #define SANITIZER_INTERCEPT_MCHECK_MPROBE SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_WCSLEN 1
-#define SANITIZER_INTERCEPT_WCSCAT (SI_POSIX || SI_WINDOWS)
+#define SANITIZER_INTERCEPT_WCSCAT SI_POSIX
 #define SANITIZER_INTERCEPT_WCSDUP SI_POSIX
 #define SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION (!SI_WINDOWS && SI_NOT_FUCHSIA)
 #define SANITIZER_INTERCEPT_BSD_SIGNAL SI_ANDROID
diff --git a/compiler-rt/test/asan/TestCases/wcscat.cpp b/compiler-rt/test/asan/TestCases/wcscat.cpp
deleted file mode 100644
index dcdff88c18ef1..0000000000000
--- a/compiler-rt/test/asan/TestCases/wcscat.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-// RUN: %clangxx_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-// RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-// RUN: %clangxx_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-
-#include <stdio.h>
-#include <wchar.h>
-
-int main() {
-  wchar_t *start = L"X means ";
-  wchar_t *append = L"dog";
-  wchar_t goodDst[12];
-  wcscpy(goodDst, start);
-  wcscat(goodDst, append);
-
-  wchar_t badDst[9];
-  wcscpy(badDst, start);
-  printf("Good so far.\n");
-  // CHECK: Good so far.
-  fflush(stdout);
-  wcscat(badDst, append); // Boom!
-  // CHECK: ERROR: AddressSanitizer: stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] at pc {{0x[0-9a-f]+}} bp {{0x[0-9a-f]+}} sp {{0x[0-9a-f]+}}
-  // CHECK: WRITE of size {{[0-9]+}} at [[ADDR:0x[0-9a-f]+]] thread T0
-  // CHECK: #0 [[ADDR:0x[0-9a-f]+]] in wcscat{{.*}}sanitizer_common_interceptors.inc:{{[0-9]+}}
-  printf("Should have failed with ASAN error.\n");
-}
\ No newline at end of file
diff --git a/compiler-rt/test/asan/TestCases/wcscpy.cpp b/compiler-rt/test/asan/TestCases/wcscpy.cpp
deleted file mode 100644
index 414d83303a960..0000000000000
--- a/compiler-rt/test/asan/TestCases/wcscpy.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-// RUN: %clangxx_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-// RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-// RUN: %clangxx_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-
-#include <stdio.h>
-#include <wchar.h>
-
-int main() {
-  wchar_t *src = L"X means dog";
-  wchar_t goodDst[12];
-  wcscpy(goodDst, src);
-
-  wchar_t badDst[7];
-  printf("Good so far.\n");
-  // CHECK: Good so far.
-  fflush(stdout);
-  wcscpy(badDst, src); // Boom!
-  // CHECK:ERROR: AddressSanitizer: stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] at pc {{0x[0-9a-f]+}} bp {{0x[0-9a-f]+}} sp {{0x[0-9a-f]+}}
-  // CHECK: WRITE of size {{[0-9]+}} at [[ADDR:0x[0-9a-f]+]] thread T0
-  // CHECK: #0 [[ADDR:0x[0-9a-f]+]] in wcscpy{{.*}}asan_interceptors.cpp:{{[0-9]+}}
-  printf("Should have failed with ASAN error.\n");
-}
\ No newline at end of file
diff --git a/compiler-rt/test/asan/TestCases/wcsncat.cpp b/compiler-rt/test/asan/TestCases/wcsncat.cpp
deleted file mode 100644
index 3ab7fc8f55d63..0000000000000
--- a/compiler-rt/test/asan/TestCases/wcsncat.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-// RUN: %clangxx_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-// RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-// RUN: %clangxx_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-
-#include <stdio.h>
-#include <wchar.h>
-
-int main() {
-  wchar_t *start = L"X means ";
-  wchar_t *append = L"dog";
-  wchar_t goodDst[15];
-  wcscpy(goodDst, start);
-  wcsncat(goodDst, append, 5);
-
-  wchar_t badDst[11];
-  wcscpy(badDst, start);
-  wcsncat(badDst, append, 1);
-  printf("Good so far.\n");
-  // CHECK: Good so far.
-  fflush(stdout);
-  wcsncat(badDst, append, 3); // Boom!
-  // CHECK: ERROR: AddressSanitizer: stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] at pc {{0x[0-9a-f]+}} bp {{0x[0-9a-f]+}} sp {{0x[0-9a-f]+}}
-  // CHECK: WRITE of size {{[0-9]+}} at [[ADDR:0x[0-9a-f]+]] thread T0
-  // CHECK: #0 [[ADDR:0x[0-9a-f]+]] in wcsncat{{.*}}sanitizer_common_interceptors.inc:{{[0-9]+}}
-  printf("Should have failed with ASAN error.\n");
-}
\ No newline at end of file
diff --git a/compiler-rt/test/asan/TestCases/wcsncpy.cpp b/compiler-rt/test/asan/TestCases/wcsncpy.cpp
deleted file mode 100644
index 6177b72990a0a..0000000000000
--- a/compiler-rt/test/asan/TestCases/wcsncpy.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-// RUN: %clangxx_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-// RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-// RUN: %clangxx_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
-
-#include <stdio.h>
-#include <wchar.h>
-
-int main() {
-  wchar_t *src = L"X means dog";
-  wchar_t goodDst[12];
-  wcsncpy(goodDst, src, 12);
-
-  wchar_t badDst[7];
-  wcsncpy(badDst, src, 7); // This should still work.
-  printf("Good so far.\n");
-  // CHECK: Good so far.
-  fflush(stdout);
-
-  wcsncpy(badDst, src, 15); // Boom!
-  // CHECK:ERROR: AddressSanitizer: stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] at pc {{0x[0-9a-f]+}} bp {{0x[0-9a-f]+}} sp {{0x[0-9a-f]+}}
-  // CHECK: WRITE of size {{[0-9]+}} at [[ADDR:0x[0-9a-f]+]] thread T0
-  // CHECK: #0 [[ADDR:0x[0-9a-f]+]] in wcsncpy{{.*}}asan_interceptors.cpp:{{[0-9]+}}
-  printf("Should have failed with ASAN error.\n");
-}
\ No newline at end of file

@thurstond thurstond enabled auto-merge (squash) October 5, 2025 18:06
Copy link

github-actions bot commented Oct 5, 2025

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff origin/main HEAD --extensions cpp,h -- compiler-rt/lib/asan/asan_interceptors.cpp compiler-rt/lib/asan/asan_interceptors.h compiler-rt/lib/asan/asan_win_static_runtime_thunk.cpp compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h

⚠️
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing origin/main to the base branch/commit you want to compare against.
⚠️

View the diff from clang-format here.
diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp
index 7c9a08b90..f6ae2d475 100644
--- a/compiler-rt/lib/asan/asan_interceptors.cpp
+++ b/compiler-rt/lib/asan/asan_interceptors.cpp
@@ -61,7 +61,7 @@ static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
   if (REAL(strnlen)) {
     return REAL(strnlen)(s, maxlen);
   }
-#endif
+#  endif
   return internal_strnlen(s, maxlen);
 }
 
diff --git a/compiler-rt/lib/asan/asan_interceptors.h b/compiler-rt/lib/asan/asan_interceptors.h
index 3e2386eaf..af091eb7d 100644
--- a/compiler-rt/lib/asan/asan_interceptors.h
+++ b/compiler-rt/lib/asan/asan_interceptors.h
@@ -128,7 +128,7 @@ DECLARE_REAL(int, memcmp, const void *a1, const void *a2, SIZE_T size)
 DECLARE_REAL(char*, strchr, const char *str, int c)
 DECLARE_REAL(SIZE_T, strlen, const char *s)
 DECLARE_REAL(char*, strncpy, char *to, const char *from, SIZE_T size)
-DECLARE_REAL(SIZE_T, strnlen, const char *s, SIZE_T maxlen)
+DECLARE_REAL(SIZE_T, strnlen, const char* s, SIZE_T maxlen)
 DECLARE_REAL(char*, strstr, const char *s1, const char *s2)
 
 #  if !SANITIZER_APPLE

@thurstond thurstond merged commit c793782 into main Oct 5, 2025
12 of 13 checks passed
@thurstond thurstond deleted the revert-160493-asan-wchar branch October 5, 2025 18:17
thurstond pushed a commit that referenced this pull request Oct 6, 2025
… wchar tests on Darwin/Android (#162028)

### Summary
Reland: wcscpy/wcsncpy interceptors and stabilize wchar tests on
Darwin/Android. Functional reland (runtime + tests).

### Context
Reland of #160493 and #161624; previously reverted by #162021 and
#162001 to restore green.

### Motivation
- Restore wchar interceptors (wcscpy/wcsncpy), broaden ASan coverage,
and improve Windows parity with narrow-string checks.
- Make tests robust across Darwin/Android to keep bots green.

### Runtime (wcscpy/wcsncpy)
- Add overlap checks; mark read/write ranges in bytes.
- Use MaybeRealWcsnlen when available to bound reads.
- Register Windows static runtime thunk where applicable.

### Tests (wcscpy/wcsncpy/wcscat/wcsncat)
- Android: keep `%env_asan_opts=log_to_stderr=1` so the ASan header is
on stderr.
- Darwin: tolerate reordering by putting all four key lines in one DAG
group:

```cpp
// CHECK-DAG: Good so far.
// CHECK-DAG: ERROR: AddressSanitizer: stack-buffer-overflow on address [[ADDR:...]] at pc {{...}} bp {{...}} sp {{...}}
// CHECK-DAG: WRITE of size {{[0-9]+}} at [[ADDR]] thread T0
// CHECK-DAG: #0 {{0x[0-9a-f]+}} in <func>
```

### Risk
- Functional reland (runtime + tests), intended to restore functionality
and maintain stability across platforms.

---------

Signed-off-by: Yixuan Cao <[email protected]>
aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 6, 2025
… on Windows" (llvm#162021)

Reverts llvm#160493 due to buildbot failures e.g.,
llvm#160493 (comment)

The fix-forward (llvm#161624) still
had failures on Darwin, and was reverted in
llvm#162001 i.e., this pull request
completes the revert to green for this patch stack.
aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 6, 2025
… wchar tests on Darwin/Android (llvm#162028)

### Summary
Reland: wcscpy/wcsncpy interceptors and stabilize wchar tests on
Darwin/Android. Functional reland (runtime + tests).

### Context
Reland of llvm#160493 and llvm#161624; previously reverted by llvm#162021 and
llvm#162001 to restore green.

### Motivation
- Restore wchar interceptors (wcscpy/wcsncpy), broaden ASan coverage,
and improve Windows parity with narrow-string checks.
- Make tests robust across Darwin/Android to keep bots green.

### Runtime (wcscpy/wcsncpy)
- Add overlap checks; mark read/write ranges in bytes.
- Use MaybeRealWcsnlen when available to bound reads.
- Register Windows static runtime thunk where applicable.

### Tests (wcscpy/wcsncpy/wcscat/wcsncat)
- Android: keep `%env_asan_opts=log_to_stderr=1` so the ASan header is
on stderr.
- Darwin: tolerate reordering by putting all four key lines in one DAG
group:

```cpp
// CHECK-DAG: Good so far.
// CHECK-DAG: ERROR: AddressSanitizer: stack-buffer-overflow on address [[ADDR:...]] at pc {{...}} bp {{...}} sp {{...}}
// CHECK-DAG: WRITE of size {{[0-9]+}} at [[ADDR]] thread T0
// CHECK-DAG: #0 {{0x[0-9a-f]+}} in <func>
```

### Risk
- Functional reland (runtime + tests), intended to restore functionality
and maintain stability across platforms.

---------

Signed-off-by: Yixuan Cao <[email protected]>
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.

2 participants