aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/compiler-rt/lib/nsan/nsan_malloc_linux.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/compiler-rt/lib/nsan/nsan_malloc_linux.cpp')
-rw-r--r--contrib/llvm-project/compiler-rt/lib/nsan/nsan_malloc_linux.cpp123
1 files changed, 123 insertions, 0 deletions
diff --git a/contrib/llvm-project/compiler-rt/lib/nsan/nsan_malloc_linux.cpp b/contrib/llvm-project/compiler-rt/lib/nsan/nsan_malloc_linux.cpp
new file mode 100644
index 000000000000..d66ee65b3674
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/nsan/nsan_malloc_linux.cpp
@@ -0,0 +1,123 @@
+//===- 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;
+
+namespace {
+struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
+ static bool UseImpl() { return !nsan_initialized; }
+};
+} // namespace
+
+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 *, 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);
+ 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;
+}
+
+#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), 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);
+ if (res == 0 && *memptr)
+ __nsan_set_value_unknown(static_cast<u8 *>(*memptr), size);
+ return res;
+}
+
+// Deprecated allocation functions (memalign, 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
+
+void __nsan::InitializeMallocInterceptors() {
+ INTERCEPT_FUNCTION(aligned_alloc);
+ INTERCEPT_FUNCTION(calloc);
+ INTERCEPT_FUNCTION(free);
+ 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);
+#endif
+}
+
+#endif