Skip to content

[tysan] Replace HandleEarlyAlloc with DlsymAlloc #120563

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

Merged
merged 1 commit into from
Dec 23, 2024

Conversation

Enna1
Copy link
Contributor

@Enna1 Enna1 commented Dec 19, 2024

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Dec 19, 2024

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

Author: Enna1 (Enna1)

Changes

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

1 Files Affected:

  • (modified) compiler-rt/lib/tysan/tysan_interceptors.cpp (+16-29)
diff --git a/compiler-rt/lib/tysan/tysan_interceptors.cpp b/compiler-rt/lib/tysan/tysan_interceptors.cpp
index 5fc6f244122727..08b1010a48ecf0 100644
--- a/compiler-rt/lib/tysan/tysan_interceptors.cpp
+++ b/compiler-rt/lib/tysan/tysan_interceptors.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "interception/interception.h"
+#include "sanitizer_common/sanitizer_allocator_dlsym.h"
 #include "sanitizer_common/sanitizer_common.h"
 #include "tysan/tysan.h"
 
@@ -28,23 +29,11 @@ extern "C" int mallopt(int param, int value);
 using namespace __sanitizer;
 using namespace __tysan;
 
-static const uptr early_alloc_buf_size = 16384;
-static uptr allocated_bytes;
-static char early_alloc_buf[early_alloc_buf_size];
-
-static bool isInEarlyAllocBuf(const void *ptr) {
-  return ((uptr)ptr >= (uptr)early_alloc_buf &&
-          ((uptr)ptr - (uptr)early_alloc_buf) < sizeof(early_alloc_buf));
-}
-
-// Handle allocation requests early (before all interceptors are setup). dlsym,
-// for example, calls calloc.
-static void *handleEarlyAlloc(uptr size) {
-  void *mem = (void *)&early_alloc_buf[allocated_bytes];
-  allocated_bytes += size;
-  CHECK_LT(allocated_bytes, early_alloc_buf_size);
-  return mem;
-}
+namespace {
+struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
+  static bool UseImpl() { return !tysan_inited; }
+};
+} // namespace
 
 INTERCEPTOR(void *, memset, void *dst, int v, uptr size) {
   if (!tysan_inited && REAL(memset) == nullptr)
@@ -111,9 +100,8 @@ INTERCEPTOR(char *, __strdup, const char *s) {
 #endif // TYSAN_INTERCEPT___STRDUP
 
 INTERCEPTOR(void *, malloc, uptr size) {
-  if (tysan_init_is_running && REAL(malloc) == nullptr)
-    return handleEarlyAlloc(size);
-
+  if (DlsymAlloc::Use())
+    return DlsymAlloc::Allocate(size);
   void *res = REAL(malloc)(size);
   if (res)
     tysan_set_type_unknown(res, size);
@@ -121,6 +109,8 @@ INTERCEPTOR(void *, malloc, uptr size) {
 }
 
 INTERCEPTOR(void *, realloc, void *ptr, uptr size) {
+  if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
+    return DlsymAlloc::Realloc(ptr, size);
   void *res = REAL(realloc)(ptr, size);
   // We might want to copy the types from the original allocation (although
   // that would require that we knew its size).
@@ -130,21 +120,18 @@ INTERCEPTOR(void *, realloc, void *ptr, uptr size) {
 }
 
 INTERCEPTOR(void *, calloc, uptr nmemb, uptr size) {
-  if (tysan_init_is_running && REAL(calloc) == nullptr)
-    return handleEarlyAlloc(nmemb * size);
-
+  if (DlsymAlloc::Use())
+    return DlsymAlloc::Callocate(nmemb, size);
   void *res = REAL(calloc)(nmemb, size);
   if (res)
     tysan_set_type_unknown(res, nmemb * size);
   return res;
 }
 
-INTERCEPTOR(void, free, void *p) {
-  // There are only a few early allocation requests,
-  // so we simply skip the free.
-  if (isInEarlyAllocBuf(p))
-    return;
-  REAL(free)(p);
+INTERCEPTOR(void, free, void *ptr) {
+  if (DlsymAlloc::PointerIsMine(ptr))
+    return DlsymAlloc::Free(ptr);
+  REAL(free)(ptr);
 }
 
 INTERCEPTOR(void *, valloc, uptr size) {

@Enna1 Enna1 merged commit 34d55df into main Dec 23, 2024
10 checks passed
@Enna1 Enna1 deleted the users/Enna1/TySan-DlsymAlloc branch December 23, 2024 01:04
@fhahn
Copy link
Contributor

fhahn commented Jan 8, 2025

Unfortunate this breaks TySan on macOS. Is DlsymAlloc supposed to work on macOS or Linux/Windows only?

@fhahn
Copy link
Contributor

fhahn commented Jan 8, 2025

Mystery solved, when using DlSymAlloc, malloc_size also needs intercepting on Apple platforms: #122133

fhahn added a commit that referenced this pull request Jan 9, 2025
After #120563 malloc_size also
needs intercepting on Apple platforms, otherwise all type-sanitized
binaries crash on startup with an objc error:
realized class 0x12345 has corrupt data pointer: malloc_size(0x567) = 0

PR: #122133
github-actions bot pushed a commit to arm/arm-toolchain that referenced this pull request Jan 10, 2025
After llvm/llvm-project#120563 malloc_size also
needs intercepting on Apple platforms, otherwise all type-sanitized
binaries crash on startup with an objc error:
realized class 0x12345 has corrupt data pointer: malloc_size(0x567) = 0

PR: llvm/llvm-project#122133
BaiXilin pushed a commit to BaiXilin/llvm-fix-vnni-instr-types that referenced this pull request Jan 12, 2025
After llvm#120563 malloc_size also
needs intercepting on Apple platforms, otherwise all type-sanitized
binaries crash on startup with an objc error:
realized class 0x12345 has corrupt data pointer: malloc_size(0x567) = 0

PR: llvm#122133
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.

5 participants