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> {
UseImpl__anon0d1da7f80111::DlsymAlloc28 static bool UseImpl() { return !nsan_initialized; }
29 };
30 } // namespace
31
INTERCEPTOR(void *,aligned_alloc,uptr align,uptr size)32 INTERCEPTOR(void *, aligned_alloc, uptr align, uptr size) {
33 return nsan_aligned_alloc(align, size);
34 }
35
INTERCEPTOR(void *,calloc,uptr nmemb,uptr size)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
INTERCEPTOR(void,free,void * ptr)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
INTERCEPTOR(void *,malloc,uptr size)50 INTERCEPTOR(void *, malloc, uptr size) {
51 if (DlsymAlloc::Use())
52 return DlsymAlloc::Allocate(size);
53 return nsan_malloc(size);
54 }
55
INTERCEPTOR(void *,realloc,void * ptr,uptr size)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
INTERCEPTOR(void *,reallocarray,void * ptr,uptr nmemb,uptr size)63 INTERCEPTOR(void *, reallocarray, void *ptr, uptr nmemb, uptr size) {
64 return nsan_reallocarray(ptr, nmemb, size);
65 }
66 #endif // SANITIZER_INTERCEPT_REALLOCARRAY
67
INTERCEPTOR(int,posix_memalign,void ** memptr,uptr align,uptr size)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
INTERCEPTOR(void *,memalign,uptr align,uptr size)74 INTERCEPTOR(void *, memalign, uptr align, uptr size) {
75 return nsan_memalign(align, size);
76 }
77
INTERCEPTOR(void *,__libc_memalign,uptr align,uptr size)78 INTERCEPTOR(void *, __libc_memalign, uptr align, uptr size) {
79 return nsan_memalign(align, size);
80 }
81 #endif
82
InitializeMallocInterceptors()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