1 //===- nsan_malloc_linux.cpp ----------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Interceptors for memory allocation functions on ELF OSes. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "interception/interception.h" 14 #include "nsan.h" 15 #include "nsan_allocator.h" 16 #include "sanitizer_common/sanitizer_allocator_dlsym.h" 17 #include "sanitizer_common/sanitizer_common.h" 18 #include "sanitizer_common/sanitizer_platform.h" 19 #include "sanitizer_common/sanitizer_platform_interceptors.h" 20 #include "sanitizer_common/sanitizer_stacktrace.h" 21 22 #if !SANITIZER_APPLE && !SANITIZER_WINDOWS 23 using namespace __sanitizer; 24 using namespace __nsan; 25 26 namespace { 27 struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> { 28 static bool UseImpl() { return !nsan_initialized; } 29 }; 30 } // namespace 31 32 INTERCEPTOR(void *, aligned_alloc, uptr align, uptr size) { 33 return nsan_aligned_alloc(align, size); 34 } 35 36 INTERCEPTOR(void *, calloc, uptr nmemb, uptr size) { 37 if (DlsymAlloc::Use()) 38 return DlsymAlloc::Callocate(nmemb, size); 39 return nsan_calloc(nmemb, size); 40 } 41 42 INTERCEPTOR(void, free, void *ptr) { 43 if (UNLIKELY(!ptr)) 44 return; 45 if (DlsymAlloc::PointerIsMine(ptr)) 46 return DlsymAlloc::Free(ptr); 47 NsanDeallocate(ptr); 48 } 49 50 INTERCEPTOR(void *, malloc, uptr size) { 51 if (DlsymAlloc::Use()) 52 return DlsymAlloc::Allocate(size); 53 return nsan_malloc(size); 54 } 55 56 INTERCEPTOR(void *, realloc, void *ptr, uptr size) { 57 if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr)) 58 return DlsymAlloc::Realloc(ptr, size); 59 return nsan_realloc(ptr, size); 60 } 61 62 #if SANITIZER_INTERCEPT_REALLOCARRAY 63 INTERCEPTOR(void *, reallocarray, void *ptr, uptr nmemb, uptr size) { 64 return nsan_reallocarray(ptr, nmemb, size); 65 } 66 #endif // SANITIZER_INTERCEPT_REALLOCARRAY 67 68 INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr size) { 69 return nsan_posix_memalign(memptr, align, size); 70 } 71 72 // Deprecated allocation functions (memalign, etc). 73 #if SANITIZER_INTERCEPT_MEMALIGN 74 INTERCEPTOR(void *, memalign, uptr align, uptr size) { 75 return nsan_memalign(align, size); 76 } 77 78 INTERCEPTOR(void *, __libc_memalign, uptr align, uptr size) { 79 return nsan_memalign(align, size); 80 } 81 #endif 82 83 void __nsan::InitializeMallocInterceptors() { 84 INTERCEPT_FUNCTION(aligned_alloc); 85 INTERCEPT_FUNCTION(calloc); 86 INTERCEPT_FUNCTION(free); 87 INTERCEPT_FUNCTION(malloc); 88 INTERCEPT_FUNCTION(posix_memalign); 89 INTERCEPT_FUNCTION(realloc); 90 #if SANITIZER_INTERCEPT_REALLOCARRAY 91 INTERCEPT_FUNCTION(reallocarray); 92 #endif 93 94 #if SANITIZER_INTERCEPT_MEMALIGN 95 INTERCEPT_FUNCTION(memalign); 96 INTERCEPT_FUNCTION(__libc_memalign); 97 #endif 98 } 99 100 #endif 101