Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_new_delete.cpp
35235 views
1
//===-- hwasan_new_delete.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
// This file is a part of HWAddressSanitizer.
10
//
11
// Interceptors for operators new and delete.
12
//===----------------------------------------------------------------------===//
13
14
#include "hwasan.h"
15
#include "interception/interception.h"
16
#include "sanitizer_common/sanitizer_allocator.h"
17
#include "sanitizer_common/sanitizer_allocator_report.h"
18
19
#include <stddef.h>
20
#include <stdlib.h>
21
22
#if HWASAN_REPLACE_OPERATORS_NEW_AND_DELETE
23
24
// TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
25
# define OPERATOR_NEW_BODY(nothrow) \
26
GET_MALLOC_STACK_TRACE; \
27
void *res = hwasan_malloc(size, &stack); \
28
if (!nothrow && UNLIKELY(!res)) \
29
ReportOutOfMemory(size, &stack); \
30
return res
31
# define OPERATOR_NEW_ALIGN_BODY(nothrow) \
32
GET_MALLOC_STACK_TRACE; \
33
void *res = hwasan_memalign(static_cast<uptr>(align), size, &stack); \
34
if (!nothrow && UNLIKELY(!res)) \
35
ReportOutOfMemory(size, &stack); \
36
return res
37
38
# define OPERATOR_DELETE_BODY \
39
GET_MALLOC_STACK_TRACE; \
40
if (ptr) \
41
hwasan_free(ptr, &stack)
42
43
#elif defined(__ANDROID__)
44
45
// We don't actually want to intercept operator new and delete on Android, but
46
// since we previously released a runtime that intercepted these functions,
47
// removing the interceptors would break ABI. Therefore we simply forward to
48
// malloc and free.
49
# define OPERATOR_NEW_BODY(nothrow) return malloc(size)
50
# define OPERATOR_DELETE_BODY free(ptr)
51
52
#endif
53
54
#ifdef OPERATOR_NEW_BODY
55
56
using namespace __hwasan;
57
58
// Fake std::nothrow_t to avoid including <new>.
59
namespace std {
60
struct nothrow_t {};
61
} // namespace std
62
63
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new(size_t size) {
64
OPERATOR_NEW_BODY(false /*nothrow*/);
65
}
66
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new[](
67
size_t size) {
68
OPERATOR_NEW_BODY(false /*nothrow*/);
69
}
70
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new(
71
size_t size, std::nothrow_t const &) {
72
OPERATOR_NEW_BODY(true /*nothrow*/);
73
}
74
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new[](
75
size_t size, std::nothrow_t const &) {
76
OPERATOR_NEW_BODY(true /*nothrow*/);
77
}
78
79
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(
80
void *ptr) NOEXCEPT {
81
OPERATOR_DELETE_BODY;
82
}
83
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
84
void *ptr) NOEXCEPT {
85
OPERATOR_DELETE_BODY;
86
}
87
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(
88
void *ptr, std::nothrow_t const &) {
89
OPERATOR_DELETE_BODY;
90
}
91
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
92
void *ptr, std::nothrow_t const &) {
93
OPERATOR_DELETE_BODY;
94
}
95
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(
96
void *ptr, size_t) NOEXCEPT {
97
OPERATOR_DELETE_BODY;
98
}
99
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
100
void *ptr, size_t) NOEXCEPT {
101
OPERATOR_DELETE_BODY;
102
}
103
104
#endif // OPERATOR_NEW_BODY
105
106
#ifdef OPERATOR_NEW_ALIGN_BODY
107
108
namespace std {
109
enum class align_val_t : size_t {};
110
} // namespace std
111
112
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new(
113
size_t size, std::align_val_t align) {
114
OPERATOR_NEW_ALIGN_BODY(false /*nothrow*/);
115
}
116
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new[](
117
size_t size, std::align_val_t align) {
118
OPERATOR_NEW_ALIGN_BODY(false /*nothrow*/);
119
}
120
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new(
121
size_t size, std::align_val_t align, std::nothrow_t const &) {
122
OPERATOR_NEW_ALIGN_BODY(true /*nothrow*/);
123
}
124
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new[](
125
size_t size, std::align_val_t align, std::nothrow_t const &) {
126
OPERATOR_NEW_ALIGN_BODY(true /*nothrow*/);
127
}
128
129
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(
130
void *ptr, std::align_val_t align) NOEXCEPT {
131
OPERATOR_DELETE_BODY;
132
}
133
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
134
void *ptr, std::align_val_t) NOEXCEPT {
135
OPERATOR_DELETE_BODY;
136
}
137
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(
138
void *ptr, std::align_val_t, std::nothrow_t const &) NOEXCEPT {
139
OPERATOR_DELETE_BODY;
140
}
141
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
142
void *ptr, std::align_val_t, std::nothrow_t const &) NOEXCEPT {
143
OPERATOR_DELETE_BODY;
144
}
145
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(
146
void *ptr, size_t, std::align_val_t) NOEXCEPT {
147
OPERATOR_DELETE_BODY;
148
}
149
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
150
void *ptr, size_t, std::align_val_t) NOEXCEPT {
151
OPERATOR_DELETE_BODY;
152
}
153
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(
154
void *ptr, size_t, std::align_val_t, std::nothrow_t const &) NOEXCEPT {
155
OPERATOR_DELETE_BODY;
156
}
157
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
158
void *ptr, size_t, std::align_val_t, std::nothrow_t const &) NOEXCEPT {
159
OPERATOR_DELETE_BODY;
160
}
161
162
#endif // OPERATOR_NEW_ALIGN_BODY
163
164