1 //===-- asan_interceptors.cc ----------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of AddressSanitizer, an address sanity checker.
11 //
12 // Interceptors for operators new and delete.
13 //===----------------------------------------------------------------------===//
14
15 #include "asan_allocator.h"
16 #include "asan_internal.h"
17 #include "asan_stack.h"
18
19 #include <stddef.h>
20
21 namespace __asan {
22 // This function is a no-op. We need it to make sure that object file
23 // with our replacements will actually be loaded from static ASan
24 // run-time library at link-time.
ReplaceOperatorsNewAndDelete()25 void ReplaceOperatorsNewAndDelete() { }
26 }
27
28 using namespace __asan; // NOLINT
29
30 // On Android new() goes through malloc interceptors.
31 // See also https://code.google.com/p/address-sanitizer/issues/detail?id=131.
32 #if !SANITIZER_ANDROID
33
34 // Fake std::nothrow_t to avoid including <new>.
35 namespace std {
36 struct nothrow_t {};
37 } // namespace std
38
39 #define OPERATOR_NEW_BODY(type) \
40 GET_STACK_TRACE_MALLOC;\
41 return asan_memalign(0, size, &stack, type);
42
43 // On OS X it's not enough to just provide our own 'operator new' and
44 // 'operator delete' implementations, because they're going to be in the
45 // runtime dylib, and the main executable will depend on both the runtime
46 // dylib and libstdc++, each of those'll have its implementation of new and
47 // delete.
48 // To make sure that C++ allocation/deallocation operators are overridden on
49 // OS X we need to intercept them using their mangled names.
50 #if !SANITIZER_MAC
51 INTERCEPTOR_ATTRIBUTE
operator new(size_t size)52 void *operator new(size_t size) { OPERATOR_NEW_BODY(FROM_NEW); }
53 INTERCEPTOR_ATTRIBUTE
operator new[](size_t size)54 void *operator new[](size_t size) { OPERATOR_NEW_BODY(FROM_NEW_BR); }
55 INTERCEPTOR_ATTRIBUTE
operator new(size_t size,std::nothrow_t const &)56 void *operator new(size_t size, std::nothrow_t const&)
57 { OPERATOR_NEW_BODY(FROM_NEW); }
58 INTERCEPTOR_ATTRIBUTE
operator new[](size_t size,std::nothrow_t const &)59 void *operator new[](size_t size, std::nothrow_t const&)
60 { OPERATOR_NEW_BODY(FROM_NEW_BR); }
61
62 #else // SANITIZER_MAC
INTERCEPTOR(void *,_Znwm,size_t size)63 INTERCEPTOR(void *, _Znwm, size_t size) {
64 OPERATOR_NEW_BODY(FROM_NEW);
65 }
INTERCEPTOR(void *,_Znam,size_t size)66 INTERCEPTOR(void *, _Znam, size_t size) {
67 OPERATOR_NEW_BODY(FROM_NEW_BR);
68 }
INTERCEPTOR(void *,_ZnwmRKSt9nothrow_t,size_t size,std::nothrow_t const &)69 INTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&) {
70 OPERATOR_NEW_BODY(FROM_NEW);
71 }
INTERCEPTOR(void *,_ZnamRKSt9nothrow_t,size_t size,std::nothrow_t const &)72 INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) {
73 OPERATOR_NEW_BODY(FROM_NEW_BR);
74 }
75 #endif
76
77 #define OPERATOR_DELETE_BODY(type) \
78 GET_STACK_TRACE_FREE;\
79 asan_free(ptr, &stack, type);
80
81 #if !SANITIZER_MAC
82 INTERCEPTOR_ATTRIBUTE
operator delete(void * ptr)83 void operator delete(void *ptr) { OPERATOR_DELETE_BODY(FROM_NEW); }
84 INTERCEPTOR_ATTRIBUTE
operator delete[](void * ptr)85 void operator delete[](void *ptr) { OPERATOR_DELETE_BODY(FROM_NEW_BR); }
86 INTERCEPTOR_ATTRIBUTE
operator delete(void * ptr,std::nothrow_t const &)87 void operator delete(void *ptr, std::nothrow_t const&)
88 { OPERATOR_DELETE_BODY(FROM_NEW); }
89 INTERCEPTOR_ATTRIBUTE
operator delete[](void * ptr,std::nothrow_t const &)90 void operator delete[](void *ptr, std::nothrow_t const&)
91 { OPERATOR_DELETE_BODY(FROM_NEW_BR); }
92
93 #else // SANITIZER_MAC
INTERCEPTOR(void,_ZdlPv,void * ptr)94 INTERCEPTOR(void, _ZdlPv, void *ptr) {
95 OPERATOR_DELETE_BODY(FROM_NEW);
96 }
INTERCEPTOR(void,_ZdaPv,void * ptr)97 INTERCEPTOR(void, _ZdaPv, void *ptr) {
98 OPERATOR_DELETE_BODY(FROM_NEW_BR);
99 }
INTERCEPTOR(void,_ZdlPvRKSt9nothrow_t,void * ptr,std::nothrow_t const &)100 INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) {
101 OPERATOR_DELETE_BODY(FROM_NEW);
102 }
INTERCEPTOR(void,_ZdaPvRKSt9nothrow_t,void * ptr,std::nothrow_t const &)103 INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) {
104 OPERATOR_DELETE_BODY(FROM_NEW_BR);
105 }
106 #endif
107
108 #endif
109