[clang] [compiler-rt] [nsan] Add shared runtime (PR #98415)

Fangrui Song via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 10 18:35:02 PDT 2024


https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/98415

>From 29b11cc74f3358c22214e5a6c9e5042f9c4a7e38 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 10 Jul 2024 16:29:08 -0700
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.5-bogner
---
 clang/lib/Driver/SanitizerArgs.cpp         |   4 +-
 clang/lib/Driver/ToolChains/CommonArgs.cpp |   4 +-
 clang/test/Driver/sanitizer-ld.c           |  18 +++
 compiler-rt/lib/nsan/CMakeLists.txt        | 113 +++++++++++++----
 compiler-rt/lib/nsan/nsan.h                |   1 +
 compiler-rt/lib/nsan/nsan.syms.extra       |   2 +-
 compiler-rt/lib/nsan/nsan_interceptors.cpp | 115 +----------------
 compiler-rt/lib/nsan/nsan_malloc_linux.cpp | 137 +++++++++++++++++++++
 8 files changed, 255 insertions(+), 139 deletions(-)
 create mode 100644 compiler-rt/lib/nsan/nsan_malloc_linux.cpp

diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 86825a6ccf7a1..1fd870b72286e 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -285,8 +285,8 @@ bool SanitizerArgs::needsFuzzerInterceptors() const {
 
 bool SanitizerArgs::needsUbsanRt() const {
   // All of these include ubsan.
-  if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() ||
-      needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() ||
+  if (needsAsanRt() || needsMsanRt() || needsNsanRt() || needsHwasanRt() ||
+      needsTsanRt() || needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() ||
       (needsScudoRt() && !requiresMinimalRuntime()))
     return false;
 
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index ab1590104b790..80a2b2bf31183 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1409,6 +1409,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
       if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid())
         HelperStaticRuntimes.push_back("memprof-preinit");
     }
+    if (SanArgs.needsNsanRt())
+      SharedRuntimes.push_back("nsan");
     if (SanArgs.needsUbsanRt()) {
       if (SanArgs.requiresMinimalRuntime())
         SharedRuntimes.push_back("ubsan_minimal");
@@ -1479,7 +1481,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
     if (SanArgs.linkCXXRuntimes())
       StaticRuntimes.push_back("msan_cxx");
   }
-  if (SanArgs.needsNsanRt())
+  if (!SanArgs.needsSharedRt() && SanArgs.needsNsanRt())
     StaticRuntimes.push_back("nsan");
   if (!SanArgs.needsSharedRt() && SanArgs.needsTsanRt()) {
     StaticRuntimes.push_back("tsan");
diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c
index e215c034070e0..48e4ea1f7dcb5 100644
--- a/clang/test/Driver/sanitizer-ld.c
+++ b/clang/test/Driver/sanitizer-ld.c
@@ -646,6 +646,24 @@
 // CHECK-NSAN-LINUX: libclang_rt.nsan.a"
 // CHECK-NSAN-LINUX: "-lpthread" "-lrt" "-lm" "-ldl" "-lresolv"
 
+// RUN: %clang -### %s 2>&1 --target=x86_64-unknown-linux -fuse-ld=ld -fsanitize=numerical -shared-libsan \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-NSAN-SHARED-LINUX %s
+
+// CHECK-NSAN-SHARED-LINUX: libclang_rt.nsan.so"
+// CHECK-NSAN-SHARED-LINUX-NOT: "-lpthread"
+// CHECK-NSAN-SHARED-LINUX-NOT: "-ldl"
+// CHECK-NSAN-SHARED-LINUX-NOT: "--dynamic-list
+
+// RUN: %clang -### %s 2>&1 --target=x86_64-unknown-linux -fsanitize=numerical,undefined \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-NSAN-UBSAN %s
+
+// CHECK-NSAN-UBSAN: "--whole-archive" "{{[^"]*}}libclang_rt.nsan.a" "--no-whole-archive"
+// CHECK-NSAN-UBSAN-NOT: libclang_rt.ubsan
+
 // CFI by itself does not link runtime libraries.
 // RUN: not %clang -fsanitize=cfi -### %s 2>&1 \
 // RUN:     --target=x86_64-unknown-linux -fuse-ld=ld -rtlib=platform \
diff --git a/compiler-rt/lib/nsan/CMakeLists.txt b/compiler-rt/lib/nsan/CMakeLists.txt
index aef9b651ab2ec..d67c3ac434d3a 100644
--- a/compiler-rt/lib/nsan/CMakeLists.txt
+++ b/compiler-rt/lib/nsan/CMakeLists.txt
@@ -6,6 +6,7 @@ set(NSAN_SOURCES
   nsan.cpp
   nsan_flags.cpp
   nsan_interceptors.cpp
+  nsan_malloc_linux.cpp
   nsan_stats.cpp
   nsan_suppressions.cpp
 )
@@ -24,30 +25,98 @@ append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC NSAN_CFLAGS)
 set(NSAN_DYNAMIC_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS})
 
 set(NSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
+set(NSAN_DYNAMIC_CFLAGS ${NSAN_CFLAGS})
 
-foreach(arch ${NSAN_SUPPORTED_ARCH})
-  add_compiler_rt_runtime(
-    clang_rt.nsan
-    STATIC
-    ARCHS ${arch}
-    SOURCES ${NSAN_SOURCES}
-            $<TARGET_OBJECTS:RTInterception.${arch}>
-            $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
-            $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
-            $<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
-            $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
-            $<TARGET_OBJECTS:RTUbsan.${arch}>
-    ADDITIONAL_HEADERS ${NSAN_HEADERS}
-    CFLAGS ${NSAN_CFLAGS}
-    PARENT_TARGET nsan
-  )
-endforeach()
-
-add_compiler_rt_object_libraries(RTNsan
+set(NSAN_COMMON_RUNTIME_OBJECT_LIBS
+  RTInterception
+  RTSanitizerCommon
+  RTSanitizerCommonLibc
+  RTSanitizerCommonCoverage
+  RTSanitizerCommonSymbolizer
+  RTSanitizerCommonSymbolizerInternal
+  RTUbsan)
+
+set(NSAN_DYNAMIC_LIBS
+  ${COMPILER_RT_UNWINDER_LINK_LIBS}
+  ${SANITIZER_CXX_ABI_LIBRARIES}
+  ${SANITIZER_COMMON_LINK_LIBS})
+
+append_list_if(COMPILER_RT_HAS_LIBDL dl NSAN_DYNAMIC_LIBS)
+append_list_if(COMPILER_RT_HAS_LIBRT rt NSAN_DYNAMIC_LIBS)
+append_list_if(COMPILER_RT_HAS_LIBM m NSAN_DYNAMIC_LIBS)
+append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread NSAN_DYNAMIC_LIBS)
+
+# Compile sources into an object library.
+
+add_compiler_rt_object_libraries(RTNsan_dynamic
+  ARCHS ${NSAN_SUPPORTED_ARCH}
+  SOURCES ${NSAN_SOURCES}
+  ADDITIONAL_HEADERS ${NSAN_HEADERS}
+  CFLAGS ${NSAN_CFLAGS})
+
+if(NOT APPLE)
+  add_compiler_rt_object_libraries(RTNsan
+      ARCHS ${NSAN_SUPPORTED_ARCH}
+      SOURCES ${NSAN_SOURCES}
+      ADDITIONAL_HEADERS ${NSAN_HEADERS}
+      CFLAGS ${NSAN_CFLAGS})
+
+  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp "")
+  add_compiler_rt_object_libraries(RTNsan_dynamic_version_script_dummy
     ARCHS ${NSAN_SUPPORTED_ARCH}
-    SOURCES ${NSAN_SOURCES}
-    ADDITIONAL_HEADERS ${NSAN_HEADERS}
-    CFLAGS ${NSAN_CFLAGS})
+    SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
+    CFLAGS ${NSAN_DYNAMIC_CFLAGS})
+endif()
+
+add_compiler_rt_runtime(
+  clang_rt.nsan
+  STATIC
+  ARCHS ${NSAN_SUPPORTED_ARCH}
+  OBJECT_LIBS RTNsan
+              ${NSAN_COMMON_RUNTIME_OBJECT_LIBS}
+  CFLAGS ${NSAN_CFLAGS}
+  PARENT_TARGET nsan)
+
+if(NOT APPLE)
+  foreach(arch ${NSAN_SUPPORTED_ARCH})
+    if (COMPILER_RT_HAS_VERSION_SCRIPT)
+      add_sanitizer_rt_version_list(clang_rt.nsan-dynamic-${arch}
+                                    LIBS clang_rt.nsan-${arch}
+                                    EXTRA nsan.syms.extra)
+      set(VERSION_SCRIPT_FLAG
+           -Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/clang_rt.nsan-dynamic-${arch}.vers)
+      # The Solaris 11.4 linker supports a subset of GNU ld version scripts,
+      # but requires a special option to enable it.
+      if (COMPILER_RT_HAS_GNU_VERSION_SCRIPT_COMPAT)
+          list(APPEND VERSION_SCRIPT_FLAG -Wl,-z,gnu-version-script-compat)
+      endif()
+      set_property(SOURCE
+        ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
+        APPEND PROPERTY
+        OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clang_rt.nsan-dynamic-${arch}.vers)
+    else()
+      set(VERSION_SCRIPT_FLAG)
+    endif()
+
+    add_compiler_rt_runtime(
+      clang_rt.nsan
+      SHARED
+      ARCHS ${arch}
+      OBJECT_LIBS ${NSAN_COMMON_RUNTIME_OBJECT_LIBS}
+        RTNsan_dynamic
+        # The only purpose of RTNsan_dynamic_version_script_dummy is to
+        # carry a dependency of the shared runtime on the version script.
+        # Replacing it with a straightforward
+        # add_dependencies(clang_rt.nsan-dynamic-${arch} clang_rt.nsan-dynamic-${arch}-version-list)
+        # generates an order-only dependency in ninja.
+        RTNsan_dynamic_version_script_dummy
+      CFLAGS ${NSAN_DYNAMIC_CFLAGS}
+      LINK_FLAGS ${NSAN_DYNAMIC_LINK_FLAGS}
+        ${VERSION_SCRIPT_FLAG}
+      LINK_LIBS ${NSAN_DYNAMIC_LIBS}
+      PARENT_TARGET nsan)
+  endforeach()
+endif()
 
 if(COMPILER_RT_INCLUDE_TESTS)
   add_subdirectory(tests)
diff --git a/compiler-rt/lib/nsan/nsan.h b/compiler-rt/lib/nsan/nsan.h
index 896e5379dfc37..0fb998b049854 100644
--- a/compiler-rt/lib/nsan/nsan.h
+++ b/compiler-rt/lib/nsan/nsan.h
@@ -55,6 +55,7 @@ extern bool nsan_initialized;
 extern bool nsan_init_is_running;
 
 void InitializeInterceptors();
+void InitializeMallocInterceptors();
 
 // See notes in nsan_platform.
 // printf-free (see comment in nsan_interceptors.cc).
diff --git a/compiler-rt/lib/nsan/nsan.syms.extra b/compiler-rt/lib/nsan/nsan.syms.extra
index f3be6d39736b7..53ce5833520b8 100644
--- a/compiler-rt/lib/nsan/nsan.syms.extra
+++ b/compiler-rt/lib/nsan/nsan.syms.extra
@@ -1,2 +1,2 @@
-nsan_*
 __nsan_*
+__ubsan_*
diff --git a/compiler-rt/lib/nsan/nsan_interceptors.cpp b/compiler-rt/lib/nsan/nsan_interceptors.cpp
index 68127f169ee46..544b44f53cc42 100644
--- a/compiler-rt/lib/nsan/nsan_interceptors.cpp
+++ b/compiler-rt/lib/nsan/nsan_interceptors.cpp
@@ -1,4 +1,4 @@
-//===-- nsan_interceptors.cc ----------------------------------------------===//
+//===- nsan_interceptors.cpp ----------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -29,26 +29,8 @@ using namespace __sanitizer;
 using __nsan::nsan_init_is_running;
 using __nsan::nsan_initialized;
 
-constexpr uptr kEarlyAllocBufSize = 16384;
-static uptr allocated_bytes;
-static char early_alloc_buf[kEarlyAllocBufSize];
-
-static bool isInEarlyAllocBuf(const void *ptr) {
-  return ((uptr)ptr >= (uptr)early_alloc_buf &&
-          ((uptr)ptr - (uptr)early_alloc_buf) < sizeof(early_alloc_buf));
-}
-
 template <typename T> T min(T a, T b) { return a < b ? a : b; }
 
-// 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, kEarlyAllocBufSize);
-  return Mem;
-}
-
 INTERCEPTOR(void *, memset, void *dst, int v, uptr size) {
   // NOTE: This guard is needed because nsan's initialization code might call
   // memset.
@@ -105,90 +87,6 @@ INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dst, const wchar_t *src, uptr size) {
   return res;
 }
 
-INTERCEPTOR(void *, malloc, uptr size) {
-  // NOTE: This guard is needed because nsan's initialization code might call
-  // malloc.
-  if (nsan_init_is_running && REAL(malloc) == nullptr)
-    return HandleEarlyAlloc(size);
-
-  void *res = REAL(malloc)(size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
-INTERCEPTOR(void *, realloc, void *ptr, uptr size) {
-  void *res = REAL(realloc)(ptr, size);
-  // FIXME: We might want to copy the types from the original allocation
-  // (although that would require that we know its size).
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
-INTERCEPTOR(void *, calloc, uptr Nmemb, uptr size) {
-  // NOTE: This guard is needed because nsan's initialization code might call
-  // calloc.
-  if (nsan_init_is_running && REAL(calloc) == nullptr) {
-    // Note: EarlyAllocBuf is initialized with zeros.
-    return HandleEarlyAlloc(Nmemb * size);
-  }
-
-  void *res = REAL(calloc)(Nmemb, size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(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 *, valloc, uptr size) {
-  void *const res = REAL(valloc)(size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
-INTERCEPTOR(void *, memalign, uptr align, uptr size) {
-  void *const res = REAL(memalign)(align, size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
-INTERCEPTOR(void *, __libc_memalign, uptr align, uptr size) {
-  void *const res = REAL(__libc_memalign)(align, size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
-INTERCEPTOR(void *, pvalloc, uptr size) {
-  void *const res = REAL(pvalloc)(size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
-INTERCEPTOR(void *, aligned_alloc, uptr align, uptr size) {
-  void *const res = REAL(aligned_alloc)(align, size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
-INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr size) {
-  int res = REAL(posix_memalign)(memptr, align, size);
-  if (res == 0 && *memptr)
-    __nsan_set_value_unknown(static_cast<u8 *>(*memptr), size);
-  return res;
-}
-
 INTERCEPTOR(char *, strfry, char *s) {
   const auto Len = internal_strlen(s);
   char *res = REAL(strfry)(s);
@@ -317,16 +215,7 @@ void __nsan::InitializeInterceptors() {
   mallopt(-3, 32 * 1024); // M_MMAP_THRESHOLD
 #endif
 
-  INTERCEPT_FUNCTION(malloc);
-  INTERCEPT_FUNCTION(calloc);
-  INTERCEPT_FUNCTION(free);
-  INTERCEPT_FUNCTION(realloc);
-  INTERCEPT_FUNCTION(valloc);
-  INTERCEPT_FUNCTION(memalign);
-  INTERCEPT_FUNCTION(__libc_memalign);
-  INTERCEPT_FUNCTION(pvalloc);
-  INTERCEPT_FUNCTION(aligned_alloc);
-  INTERCEPT_FUNCTION(posix_memalign);
+  InitializeMallocInterceptors();
 
   INTERCEPT_FUNCTION(memset);
   INTERCEPT_FUNCTION(wmemset);
diff --git a/compiler-rt/lib/nsan/nsan_malloc_linux.cpp b/compiler-rt/lib/nsan/nsan_malloc_linux.cpp
new file mode 100644
index 0000000000000..3bfc16f69b9be
--- /dev/null
+++ b/compiler-rt/lib/nsan/nsan_malloc_linux.cpp
@@ -0,0 +1,137 @@
+//===- nsan_malloc_linux.cpp ----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Interceptors for memory allocation functions on ELF OSes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "interception/interception.h"
+#include "nsan/nsan.h"
+#include "sanitizer_common/sanitizer_allocator_dlsym.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_platform.h"
+#include "sanitizer_common/sanitizer_platform_interceptors.h"
+
+#if !SANITIZER_APPLE && !SANITIZER_WINDOWS
+using namespace __sanitizer;
+using __nsan::nsan_initialized;
+
+struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
+  static bool UseImpl() { return !nsan_initialized; }
+};
+
+INTERCEPTOR(void *, aligned_alloc, uptr align, uptr size) {
+  void *res = REAL(aligned_alloc)(align, size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+
+INTERCEPTOR(void *, calloc, uptr nmemb, uptr size) {
+  if (DlsymAlloc::Use())
+    return DlsymAlloc::Callocate(nmemb, size);
+
+  void *res = REAL(calloc)(nmemb, size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), nmemb * size);
+  return res;
+}
+
+INTERCEPTOR(void, free, void *ptr) {
+  if (DlsymAlloc::PointerIsMine(ptr))
+    return DlsymAlloc::Free(ptr);
+  REAL(free)(ptr);
+}
+
+INTERCEPTOR(void *, realloc, void *ptr, uptr size) {
+  if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
+    return DlsymAlloc::Realloc(ptr, size);
+  void *res = REAL(realloc)(ptr, size);
+  // TODO: We might want to copy the types from the original allocation
+  // (although that would require that we know its size).
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+
+INTERCEPTOR(void *, malloc, uptr size) {
+  if (DlsymAlloc::Use())
+    return DlsymAlloc::Allocate(size);
+
+  void *res = REAL(malloc)(size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+
+INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr size) {
+  int res = REAL(posix_memalign)(memptr, align, size);
+  if (res == 0 && *memptr)
+    __nsan_set_value_unknown(static_cast<u8 *>(*memptr), size);
+  return res;
+}
+
+#if SANITIZER_INTERCEPT_REALLOCARRAY
+INTERCEPTOR(void *, reallocarray, void *ptr, uptr nmemb, uptr size) {
+  void *res = REAL(reallocarray)(ptr, nmemb, size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+}
+#endif // SANITIZER_INTERCEPT_REALLOCARRAY
+
+// Deprecated allocation functions (memalign, pvalloc, valloc, etc).
+#if SANITIZER_INTERCEPT_MEMALIGN
+INTERCEPTOR(void *, memalign, uptr align, uptr size) {
+  void *const res = REAL(memalign)(align, size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+
+INTERCEPTOR(void *, __libc_memalign, uptr align, uptr size) {
+  void *const res = REAL(__libc_memalign)(align, size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+#endif
+
+#if SANITIZER_INTERCEPT_PVALLOC
+INTERCEPTOR(void *, pvalloc, uptr size) {
+  void *const res = REAL(pvalloc)(size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+#endif
+
+INTERCEPTOR(void *, valloc, uptr size) {
+  void *const res = REAL(valloc)(size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+
+void __nsan::InitializeMallocInterceptors() {
+  INTERCEPT_FUNCTION(aligned_alloc);
+  INTERCEPT_FUNCTION(calloc);
+  INTERCEPT_FUNCTION(free);
+  INTERCEPT_FUNCTION(malloc);
+  INTERCEPT_FUNCTION(posix_memalign);
+  INTERCEPT_FUNCTION(realloc);
+
+  INTERCEPT_FUNCTION(memalign);
+  INTERCEPT_FUNCTION(__libc_memalign);
+  INTERCEPT_FUNCTION(pvalloc);
+  INTERCEPT_FUNCTION(valloc);
+#if SANITIZER_INTERCEPT_REALLOCARRAY
+  INTERCEPT_FUNCTION(reallocarray);
+#endif
+}
+
+#endif

>From a7f65a66ef956a0516f6034b1e6b7db450d418fd Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 10 Jul 2024 16:34:11 -0700
Subject: [PATCH 2/2] .

Created using spr 1.3.5-bogner
---
 compiler-rt/lib/nsan/nsan_malloc_linux.cpp | 54 ++++++++--------------
 1 file changed, 19 insertions(+), 35 deletions(-)

diff --git a/compiler-rt/lib/nsan/nsan_malloc_linux.cpp b/compiler-rt/lib/nsan/nsan_malloc_linux.cpp
index 3bfc16f69b9be..840521eac2fd3 100644
--- a/compiler-rt/lib/nsan/nsan_malloc_linux.cpp
+++ b/compiler-rt/lib/nsan/nsan_malloc_linux.cpp
@@ -48,6 +48,15 @@ INTERCEPTOR(void, free, void *ptr) {
   REAL(free)(ptr);
 }
 
+INTERCEPTOR(void *, malloc, uptr size) {
+  if (DlsymAlloc::Use())
+    return DlsymAlloc::Allocate(size);
+  void *res = REAL(malloc)(size);
+  if (res)
+    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+  return res;
+}
+
 INTERCEPTOR(void *, realloc, void *ptr, uptr size) {
   if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
     return DlsymAlloc::Realloc(ptr, size);
@@ -59,15 +68,14 @@ INTERCEPTOR(void *, realloc, void *ptr, uptr size) {
   return res;
 }
 
-INTERCEPTOR(void *, malloc, uptr size) {
-  if (DlsymAlloc::Use())
-    return DlsymAlloc::Allocate(size);
-
-  void *res = REAL(malloc)(size);
+#if SANITIZER_INTERCEPT_REALLOCARRAY
+INTERCEPTOR(void *, reallocarray, void *ptr, uptr nmemb, uptr size) {
+  void *res = REAL(reallocarray)(ptr, nmemb, size);
   if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
+    __nsan_set_value_unknown(static_cast<u8 *>(res), nmemb * size);
   return res;
 }
+#endif // SANITIZER_INTERCEPT_REALLOCARRAY
 
 INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr size) {
   int res = REAL(posix_memalign)(memptr, align, size);
@@ -76,15 +84,7 @@ INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr size) {
   return res;
 }
 
-#if SANITIZER_INTERCEPT_REALLOCARRAY
-INTERCEPTOR(void *, reallocarray, void *ptr, uptr nmemb, uptr size) {
-  void *res = REAL(reallocarray)(ptr, nmemb, size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-}
-#endif // SANITIZER_INTERCEPT_REALLOCARRAY
-
-// Deprecated allocation functions (memalign, pvalloc, valloc, etc).
+// Deprecated allocation functions (memalign, etc).
 #if SANITIZER_INTERCEPT_MEMALIGN
 INTERCEPTOR(void *, memalign, uptr align, uptr size) {
   void *const res = REAL(memalign)(align, size);
@@ -101,22 +101,6 @@ INTERCEPTOR(void *, __libc_memalign, uptr align, uptr size) {
 }
 #endif
 
-#if SANITIZER_INTERCEPT_PVALLOC
-INTERCEPTOR(void *, pvalloc, uptr size) {
-  void *const res = REAL(pvalloc)(size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-#endif
-
-INTERCEPTOR(void *, valloc, uptr size) {
-  void *const res = REAL(valloc)(size);
-  if (res)
-    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
-  return res;
-}
-
 void __nsan::InitializeMallocInterceptors() {
   INTERCEPT_FUNCTION(aligned_alloc);
   INTERCEPT_FUNCTION(calloc);
@@ -124,13 +108,13 @@ void __nsan::InitializeMallocInterceptors() {
   INTERCEPT_FUNCTION(malloc);
   INTERCEPT_FUNCTION(posix_memalign);
   INTERCEPT_FUNCTION(realloc);
+#if SANITIZER_INTERCEPT_REALLOCARRAY
+  INTERCEPT_FUNCTION(reallocarray);
+#endif
 
+#if SANITIZER_INTERCEPT_MEMALIGN
   INTERCEPT_FUNCTION(memalign);
   INTERCEPT_FUNCTION(__libc_memalign);
-  INTERCEPT_FUNCTION(pvalloc);
-  INTERCEPT_FUNCTION(valloc);
-#if SANITIZER_INTERCEPT_REALLOCARRAY
-  INTERCEPT_FUNCTION(reallocarray);
 #endif
 }
 



More information about the cfe-commits mailing list