[compiler-rt] e93d609 - [rtsan] Fix sanitizer_common/TestCases/dlsym_alloc.c (#216579)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 10:56:08 PDT 2026


Author: Chris Apple
Date: 2026-08-18T10:56:03-07:00
New Revision: e93d6090dc1e8d4122512a3bab66929579e47bd4

URL: https://github.com/llvm/llvm-project/commit/e93d6090dc1e8d4122512a3bab66929579e47bd4
DIFF: https://github.com/llvm/llvm-project/commit/e93d6090dc1e8d4122512a3bab66929579e47bd4.diff

LOG: [rtsan] Fix sanitizer_common/TestCases/dlsym_alloc.c (#216579)

This test crashes on `free(NULL)` when DlsymAlloc is being used. This is
because `DlysmAlloc::Free` seems to crash on linux when it's called with
`nullptr`.

The vast majority of other sanitizers guard against it on the sanitizer
side in this way:


https://github.com/llvm/llvm-project/blob/65e0fe689bb7c1a6516644c27c25c3fe3c8b1ac7/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp#L728


https://github.com/llvm/llvm-project/blob/65e0fe689bb7c1a6516644c27c25c3fe3c8b1ac7/compiler-rt/lib/lsan/lsan_interceptors.cpp#L78

For example.

Added: 
    

Modified: 
    compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
index 0ec691b54768b..93bddf9e5f6bc 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
@@ -869,28 +869,32 @@ INTERCEPTOR(void *, calloc, SIZE_T num, SIZE_T size) {
 }
 
 INTERCEPTOR(void, free, void *ptr) {
-  if (DlsymAlloc::PointerIsMine(ptr))
-    return DlsymAlloc::Free(ptr);
-
   // According to the C and C++ standard, freeing a nullptr is guaranteed to be
   // a no-op (and thus real-time safe). This can be confirmed for looking at
   // __libc_free in the glibc source.
-  if (ptr != nullptr)
-    __rtsan_notify_intercepted_call("free");
+  // Crucially must be done before DlsymAlloc::Free, as it can crash on
+  // nullptr input on linux.
+  if (UNLIKELY(!ptr))
+    return;
+
+  if (DlsymAlloc::PointerIsMine(ptr))
+    return DlsymAlloc::Free(ptr);
+
+  __rtsan_notify_intercepted_call("free");
 
   return REAL(free)(ptr);
 }
 
 #if SANITIZER_INTERCEPT_FREE_SIZED
 INTERCEPTOR(void, free_sized, void *ptr, SIZE_T size) {
+  // see above comment in `free` interceptor
+  if (UNLIKELY(!ptr))
+    return;
+
   if (DlsymAlloc::PointerIsMine(ptr))
     return DlsymAlloc::Free(ptr);
 
-  // According to the C and C++ standard, freeing a nullptr is guaranteed to be
-  // a no-op (and thus real-time safe). This can be confirmed for looking at
-  // __libc_free in the glibc source.
-  if (ptr != nullptr)
-    __rtsan_notify_intercepted_call("free_sized");
+  __rtsan_notify_intercepted_call("free_sized");
 
   if (REAL(free_sized))
     return REAL(free_sized)(ptr, size);
@@ -904,14 +908,14 @@ INTERCEPTOR(void, free_sized, void *ptr, SIZE_T size) {
 #if SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED
 INTERCEPTOR(void, free_aligned_sized, void *ptr, SIZE_T alignment,
             SIZE_T size) {
+  // see above comment in `free` interceptor
+  if (UNLIKELY(!ptr))
+    return;
+
   if (DlsymAlloc::PointerIsMine(ptr))
     return DlsymAlloc::Free(ptr);
 
-  // According to the C and C++ standard, freeing a nullptr is guaranteed to be
-  // a no-op (and thus real-time safe). This can be confirmed for looking at
-  // __libc_free in the glibc source.
-  if (ptr != nullptr)
-    __rtsan_notify_intercepted_call("free_aligned_sized");
+  __rtsan_notify_intercepted_call("free_aligned_sized");
 
   if (REAL(free_aligned_sized))
     return REAL(free_aligned_sized)(ptr, alignment, size);


        


More information about the llvm-commits mailing list