Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/tysan/tysan_interceptors.cpp
213766 views
1
//===-- tysan_interceptors.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 TypeSanitizer.
10
//
11
// Interceptors for standard library functions.
12
//===----------------------------------------------------------------------===//
13
14
#include "interception/interception.h"
15
#include "sanitizer_common/sanitizer_allocator_dlsym.h"
16
#include "sanitizer_common/sanitizer_common.h"
17
#include "tysan/tysan.h"
18
19
#if SANITIZER_LINUX && !SANITIZER_ANDROID
20
#define TYSAN_INTERCEPT___STRDUP 1
21
#else
22
#define TYSAN_INTERCEPT___STRDUP 0
23
#endif
24
25
#if SANITIZER_LINUX
26
extern "C" int mallopt(int param, int value);
27
#endif
28
29
using namespace __sanitizer;
30
using namespace __tysan;
31
32
namespace {
33
struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
34
static bool UseImpl() { return !tysan_inited; }
35
};
36
} // namespace
37
38
INTERCEPTOR(void *, memset, void *dst, int v, uptr size) {
39
if (!tysan_inited && REAL(memset) == nullptr)
40
return internal_memset(dst, v, size);
41
42
void *res = REAL(memset)(dst, v, size);
43
tysan_set_type_unknown(dst, size);
44
return res;
45
}
46
47
INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) {
48
if (!tysan_inited && REAL(memmove) == nullptr)
49
return internal_memmove(dst, src, size);
50
51
void *res = REAL(memmove)(dst, src, size);
52
tysan_copy_types(dst, src, size);
53
return res;
54
}
55
56
INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) {
57
if (!tysan_inited && REAL(memcpy) == nullptr) {
58
// memmove is used here because on some platforms this will also
59
// intercept the memmove implementation.
60
return internal_memmove(dst, src, size);
61
}
62
63
void *res = REAL(memcpy)(dst, src, size);
64
tysan_copy_types(dst, src, size);
65
return res;
66
}
67
68
INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,
69
int fd, OFF_T offset) {
70
void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);
71
if (res != (void *)-1)
72
tysan_set_type_unknown(res, RoundUpTo(length, GetPageSize()));
73
return res;
74
}
75
76
#if !SANITIZER_APPLE
77
INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,
78
int fd, OFF64_T offset) {
79
void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);
80
if (res != (void *)-1)
81
tysan_set_type_unknown(res, RoundUpTo(length, GetPageSize()));
82
return res;
83
}
84
#endif
85
86
INTERCEPTOR(char *, strdup, const char *s) {
87
char *res = REAL(strdup)(s);
88
if (res)
89
tysan_copy_types(res, const_cast<char *>(s), internal_strlen(s));
90
return res;
91
}
92
93
#if TYSAN_INTERCEPT___STRDUP
94
INTERCEPTOR(char *, __strdup, const char *s) {
95
char *res = REAL(__strdup)(s);
96
if (res)
97
tysan_copy_types(res, const_cast<char *>(s), internal_strlen(s));
98
return res;
99
}
100
#endif // TYSAN_INTERCEPT___STRDUP
101
102
INTERCEPTOR(void *, malloc, uptr size) {
103
if (DlsymAlloc::Use())
104
return DlsymAlloc::Allocate(size);
105
void *res = REAL(malloc)(size);
106
if (res)
107
tysan_set_type_unknown(res, size);
108
return res;
109
}
110
111
#if SANITIZER_APPLE
112
INTERCEPTOR(uptr, malloc_size, void *ptr) {
113
if (DlsymAlloc::PointerIsMine(ptr))
114
return DlsymAlloc::GetSize(ptr);
115
return REAL(malloc_size)(ptr);
116
}
117
#endif
118
119
INTERCEPTOR(void *, realloc, void *ptr, uptr size) {
120
if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
121
return DlsymAlloc::Realloc(ptr, size);
122
void *res = REAL(realloc)(ptr, size);
123
// We might want to copy the types from the original allocation (although
124
// that would require that we knew its size).
125
if (res)
126
tysan_set_type_unknown(res, size);
127
return res;
128
}
129
130
INTERCEPTOR(void *, calloc, uptr nmemb, uptr size) {
131
if (DlsymAlloc::Use())
132
return DlsymAlloc::Callocate(nmemb, size);
133
void *res = REAL(calloc)(nmemb, size);
134
if (res)
135
tysan_set_type_unknown(res, nmemb * size);
136
return res;
137
}
138
139
INTERCEPTOR(void, free, void *ptr) {
140
if (DlsymAlloc::PointerIsMine(ptr))
141
return DlsymAlloc::Free(ptr);
142
REAL(free)(ptr);
143
}
144
145
INTERCEPTOR(void *, valloc, uptr size) {
146
void *res = REAL(valloc)(size);
147
if (res)
148
tysan_set_type_unknown(res, size);
149
return res;
150
}
151
152
#if SANITIZER_INTERCEPT_MEMALIGN
153
INTERCEPTOR(void *, memalign, uptr alignment, uptr size) {
154
void *res = REAL(memalign)(alignment, size);
155
if (res)
156
tysan_set_type_unknown(res, size);
157
return res;
158
}
159
#define TYSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)
160
#else
161
#define TYSAN_MAYBE_INTERCEPT_MEMALIGN
162
#endif // SANITIZER_INTERCEPT_MEMALIGN
163
164
#if SANITIZER_INTERCEPT___LIBC_MEMALIGN
165
INTERCEPTOR(void *, __libc_memalign, uptr alignment, uptr size) {
166
void *res = REAL(__libc_memalign)(alignment, size);
167
if (res)
168
tysan_set_type_unknown(res, size);
169
return res;
170
}
171
#define TYSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN \
172
INTERCEPT_FUNCTION(__libc_memalign)
173
#else
174
#define TYSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN
175
#endif // SANITIZER_INTERCEPT___LIBC_MEMALIGN
176
177
#if SANITIZER_INTERCEPT_PVALLOC
178
INTERCEPTOR(void *, pvalloc, uptr size) {
179
void *res = REAL(pvalloc)(size);
180
if (res)
181
tysan_set_type_unknown(res, size);
182
return res;
183
}
184
#define TYSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)
185
#else
186
#define TYSAN_MAYBE_INTERCEPT_PVALLOC
187
#endif // SANITIZER_INTERCEPT_PVALLOC
188
189
#if SANITIZER_INTERCEPT_ALIGNED_ALLOC
190
INTERCEPTOR(void *, aligned_alloc, uptr alignment, uptr size) {
191
void *res = REAL(aligned_alloc)(alignment, size);
192
if (res)
193
tysan_set_type_unknown(res, size);
194
return res;
195
}
196
#define TYSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc)
197
#else
198
#define TYSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC
199
#endif
200
201
INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {
202
int res = REAL(posix_memalign)(memptr, alignment, size);
203
if (res == 0 && *memptr)
204
tysan_set_type_unknown(*memptr, size);
205
return res;
206
}
207
208
namespace __tysan {
209
void InitializeInterceptors() {
210
static int inited = 0;
211
CHECK_EQ(inited, 0);
212
213
// Instruct libc malloc to consume less memory.
214
#if SANITIZER_LINUX
215
mallopt(1, 0); // M_MXFAST
216
mallopt(-3, 32 * 1024); // M_MMAP_THRESHOLD
217
#endif
218
219
INTERCEPT_FUNCTION(mmap);
220
221
INTERCEPT_FUNCTION(mmap64);
222
223
INTERCEPT_FUNCTION(strdup);
224
#if TYSAN_INTERCEPT___STRDUP
225
INTERCEPT_FUNCTION(__strdup);
226
#endif
227
228
INTERCEPT_FUNCTION(malloc);
229
INTERCEPT_FUNCTION(calloc);
230
INTERCEPT_FUNCTION(free);
231
INTERCEPT_FUNCTION(realloc);
232
INTERCEPT_FUNCTION(valloc);
233
TYSAN_MAYBE_INTERCEPT_MEMALIGN;
234
TYSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN;
235
TYSAN_MAYBE_INTERCEPT_PVALLOC;
236
TYSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC
237
INTERCEPT_FUNCTION(posix_memalign);
238
239
INTERCEPT_FUNCTION(memset);
240
INTERCEPT_FUNCTION(memmove);
241
INTERCEPT_FUNCTION(memcpy);
242
243
inited = 1;
244
}
245
} // namespace __tysan
246
247