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
23using namespace __sanitizer;
24using namespace __nsan;
25
26namespace {
27struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
28 static bool UseImpl() { return !nsan_initialized; }
29};
30} // namespace
31
32INTERCEPTOR(void *, aligned_alloc, uptr align, uptr size) {
33 return nsan_aligned_alloc(alignment: align, size);
34}
35
36INTERCEPTOR(void *, calloc, uptr nmemb, uptr size) {
37 if (DlsymAlloc::Use())
38 return DlsymAlloc::Callocate(nmemb, size);
39 return nsan_calloc(nmemb, size);
40}
41
42INTERCEPTOR(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
50INTERCEPTOR(void *, malloc, uptr size) {
51 if (DlsymAlloc::Use())
52 return DlsymAlloc::Allocate(size_in_bytes: size);
53 return nsan_malloc(size);
54}
55
56INTERCEPTOR(void *, realloc, void *ptr, uptr size) {
57 if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
58 return DlsymAlloc::Realloc(ptr, new_size: size);
59 return nsan_realloc(ptr, size);
60}
61
62#if SANITIZER_INTERCEPT_REALLOCARRAY
63INTERCEPTOR(void *, reallocarray, void *ptr, uptr nmemb, uptr size) {
64 return nsan_reallocarray(ptr, nmemb, size);
65}
66#endif // SANITIZER_INTERCEPT_REALLOCARRAY
67
68INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr size) {
69 return nsan_posix_memalign(memptr, alignment: align, size);
70}
71
72// Deprecated allocation functions (memalign, etc).
73#if SANITIZER_INTERCEPT_MEMALIGN
74INTERCEPTOR(void *, memalign, uptr align, uptr size) {
75 return nsan_memalign(alignment: align, size);
76}
77
78INTERCEPTOR(void *, __libc_memalign, uptr align, uptr size) {
79 return nsan_memalign(alignment: align, size);
80}
81#endif
82
83void __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