xref: /llvm-project/compiler-rt/lib/nsan/nsan_malloc_linux.cpp (revision 652707a6457eeb3927a1fe82e6b2cbc2a1fa22f5)
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