Daily bump.
[official-gcc.git] / libsanitizer / asan / asan_interceptors.cc
blob552cf9347af531c35b55407de800bd141aa491d1
1 //===-- asan_interceptors.cc ----------------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of AddressSanitizer, an address sanity checker.
9 //
10 // Intercept various libc functions.
11 //===----------------------------------------------------------------------===//
13 #include "asan_interceptors.h"
14 #include "asan_allocator.h"
15 #include "asan_internal.h"
16 #include "asan_mapping.h"
17 #include "asan_poisoning.h"
18 #include "asan_report.h"
19 #include "asan_stack.h"
20 #include "asan_stats.h"
21 #include "asan_suppressions.h"
22 #include "lsan/lsan_common.h"
23 #include "sanitizer_common/sanitizer_libc.h"
25 // There is no general interception at all on Fuchsia.
26 // Only the functions in asan_interceptors_memintrinsics.cc are
27 // really defined to replace libc functions.
28 #if !SANITIZER_FUCHSIA
30 #if SANITIZER_POSIX
31 #include "sanitizer_common/sanitizer_posix.h"
32 #endif
34 #if defined(__i386) && SANITIZER_LINUX
35 #define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1"
36 #elif defined(__mips__) && SANITIZER_LINUX
37 #define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.2"
38 #endif
40 namespace __asan {
42 #define ASAN_READ_STRING_OF_LEN(ctx, s, len, n) \
43 ASAN_READ_RANGE((ctx), (s), \
44 common_flags()->strict_string_checks ? (len) + 1 : (n))
46 #define ASAN_READ_STRING(ctx, s, n) \
47 ASAN_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n))
49 static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
50 #if SANITIZER_INTERCEPT_STRNLEN
51 if (REAL(strnlen)) {
52 return REAL(strnlen)(s, maxlen);
54 #endif
55 return internal_strnlen(s, maxlen);
58 void SetThreadName(const char *name) {
59 AsanThread *t = GetCurrentThread();
60 if (t)
61 asanThreadRegistry().SetThreadName(t->tid(), name);
64 int OnExit() {
65 if (CAN_SANITIZE_LEAKS && common_flags()->detect_leaks &&
66 __lsan::HasReportedLeaks()) {
67 return common_flags()->exitcode;
69 // FIXME: ask frontend whether we need to return failure.
70 return 0;
73 } // namespace __asan
75 // ---------------------- Wrappers ---------------- {{{1
76 using namespace __asan; // NOLINT
78 DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr)
79 DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
81 #define ASAN_INTERCEPTOR_ENTER(ctx, func) \
82 AsanInterceptorContext _ctx = {#func}; \
83 ctx = (void *)&_ctx; \
84 (void) ctx; \
86 #define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name)
87 #define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
88 ASAN_INTERCEPT_FUNC_VER(name, ver)
89 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
90 ASAN_WRITE_RANGE(ctx, ptr, size)
91 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
92 ASAN_READ_RANGE(ctx, ptr, size)
93 #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
94 ASAN_INTERCEPTOR_ENTER(ctx, func); \
95 do { \
96 if (asan_init_is_running) \
97 return REAL(func)(__VA_ARGS__); \
98 if (SANITIZER_MAC && UNLIKELY(!asan_inited)) \
99 return REAL(func)(__VA_ARGS__); \
100 ENSURE_ASAN_INITED(); \
101 } while (false)
102 #define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \
103 do { \
104 } while (false)
105 #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
106 do { \
107 } while (false)
108 #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
109 do { \
110 } while (false)
111 #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
112 do { \
113 } while (false)
114 #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name)
115 // Should be asanThreadRegistry().SetThreadNameByUserId(thread, name)
116 // But asan does not remember UserId's for threads (pthread_t);
117 // and remembers all ever existed threads, so the linear search by UserId
118 // can be slow.
119 #define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
120 do { \
121 } while (false)
122 #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
123 // Strict init-order checking is dlopen-hostile:
124 // https://github.com/google/sanitizers/issues/178
125 #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \
126 do { \
127 if (flags()->strict_init_order) \
128 StopInitOrderChecking(); \
129 CheckNoDeepBind(filename, flag); \
130 } while (false)
131 #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
132 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle)
133 #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED()
134 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!asan_inited)
135 #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \
136 if (AsanThread *t = GetCurrentThread()) { \
137 *begin = t->tls_begin(); \
138 *end = t->tls_end(); \
139 } else { \
140 *begin = *end = 0; \
143 #define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \
144 do { \
145 ASAN_INTERCEPTOR_ENTER(ctx, memmove); \
146 ASAN_MEMMOVE_IMPL(ctx, to, from, size); \
147 } while (false)
149 #define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \
150 do { \
151 ASAN_INTERCEPTOR_ENTER(ctx, memcpy); \
152 ASAN_MEMCPY_IMPL(ctx, to, from, size); \
153 } while (false)
155 #define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \
156 do { \
157 ASAN_INTERCEPTOR_ENTER(ctx, memset); \
158 ASAN_MEMSET_IMPL(ctx, block, c, size); \
159 } while (false)
161 #include "sanitizer_common/sanitizer_common_interceptors.inc"
162 #include "sanitizer_common/sanitizer_signal_interceptors.inc"
164 // Syscall interceptors don't have contexts, we don't support suppressions
165 // for them.
166 #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(nullptr, p, s)
167 #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(nullptr, p, s)
168 #define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
169 do { \
170 (void)(p); \
171 (void)(s); \
172 } while (false)
173 #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \
174 do { \
175 (void)(p); \
176 (void)(s); \
177 } while (false)
178 #include "sanitizer_common/sanitizer_common_syscalls.inc"
180 struct ThreadStartParam {
181 atomic_uintptr_t t;
182 atomic_uintptr_t is_registered;
185 #if ASAN_INTERCEPT_PTHREAD_CREATE
186 static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
187 ThreadStartParam *param = reinterpret_cast<ThreadStartParam *>(arg);
188 AsanThread *t = nullptr;
189 while ((t = reinterpret_cast<AsanThread *>(
190 atomic_load(&param->t, memory_order_acquire))) == nullptr)
191 internal_sched_yield();
192 SetCurrentThread(t);
193 return t->ThreadStart(GetTid(), &param->is_registered);
196 INTERCEPTOR(int, pthread_create, void *thread,
197 void *attr, void *(*start_routine)(void*), void *arg) {
198 EnsureMainThreadIDIsCorrect();
199 // Strict init-order checking is thread-hostile.
200 if (flags()->strict_init_order)
201 StopInitOrderChecking();
202 GET_STACK_TRACE_THREAD;
203 int detached = 0;
204 if (attr)
205 REAL(pthread_attr_getdetachstate)(attr, &detached);
206 ThreadStartParam param;
207 atomic_store(&param.t, 0, memory_order_relaxed);
208 atomic_store(&param.is_registered, 0, memory_order_relaxed);
209 int result;
211 // Ignore all allocations made by pthread_create: thread stack/TLS may be
212 // stored by pthread for future reuse even after thread destruction, and
213 // the linked list it's stored in doesn't even hold valid pointers to the
214 // objects, the latter are calculated by obscure pointer arithmetic.
215 #if CAN_SANITIZE_LEAKS
216 __lsan::ScopedInterceptorDisabler disabler;
217 #endif
218 result = REAL(pthread_create)(thread, attr, asan_thread_start, &param);
220 if (result == 0) {
221 u32 current_tid = GetCurrentTidOrInvalid();
222 AsanThread *t =
223 AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
224 atomic_store(&param.t, reinterpret_cast<uptr>(t), memory_order_release);
225 // Wait until the AsanThread object is initialized and the ThreadRegistry
226 // entry is in "started" state. One reason for this is that after this
227 // interceptor exits, the child thread's stack may be the only thing holding
228 // the |arg| pointer. This may cause LSan to report a leak if leak checking
229 // happens at a point when the interceptor has already exited, but the stack
230 // range for the child thread is not yet known.
231 while (atomic_load(&param.is_registered, memory_order_acquire) == 0)
232 internal_sched_yield();
234 return result;
237 INTERCEPTOR(int, pthread_join, void *t, void **arg) {
238 return real_pthread_join(t, arg);
241 DEFINE_REAL_PTHREAD_FUNCTIONS
242 #endif // ASAN_INTERCEPT_PTHREAD_CREATE
244 #if ASAN_INTERCEPT_SWAPCONTEXT
245 static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) {
246 // Align to page size.
247 uptr PageSize = GetPageSizeCached();
248 uptr bottom = stack & ~(PageSize - 1);
249 ssize += stack - bottom;
250 ssize = RoundUpTo(ssize, PageSize);
251 static const uptr kMaxSaneContextStackSize = 1 << 22; // 4 Mb
252 if (AddrIsInMem(bottom) && ssize && ssize <= kMaxSaneContextStackSize) {
253 PoisonShadow(bottom, ssize, 0);
257 INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp,
258 struct ucontext_t *ucp) {
259 static bool reported_warning = false;
260 if (!reported_warning) {
261 Report("WARNING: ASan doesn't fully support makecontext/swapcontext "
262 "functions and may produce false positives in some cases!\n");
263 reported_warning = true;
265 // Clear shadow memory for new context (it may share stack
266 // with current context).
267 uptr stack, ssize;
268 ReadContextStack(ucp, &stack, &ssize);
269 ClearShadowMemoryForContextStack(stack, ssize);
270 #if __has_attribute(__indirect_return__) && \
271 (defined(__x86_64__) || defined(__i386__))
272 int (*real_swapcontext)(struct ucontext_t *, struct ucontext_t *)
273 __attribute__((__indirect_return__))
274 = REAL(swapcontext);
275 int res = real_swapcontext(oucp, ucp);
276 #else
277 int res = REAL(swapcontext)(oucp, ucp);
278 #endif
279 // swapcontext technically does not return, but program may swap context to
280 // "oucp" later, that would look as if swapcontext() returned 0.
281 // We need to clear shadow for ucp once again, as it may be in arbitrary
282 // state.
283 ClearShadowMemoryForContextStack(stack, ssize);
284 return res;
286 #endif // ASAN_INTERCEPT_SWAPCONTEXT
288 #if SANITIZER_NETBSD
289 #define longjmp __longjmp14
290 #define siglongjmp __siglongjmp14
291 #endif
293 INTERCEPTOR(void, longjmp, void *env, int val) {
294 __asan_handle_no_return();
295 REAL(longjmp)(env, val);
298 #if ASAN_INTERCEPT__LONGJMP
299 INTERCEPTOR(void, _longjmp, void *env, int val) {
300 __asan_handle_no_return();
301 REAL(_longjmp)(env, val);
303 #endif
305 #if ASAN_INTERCEPT___LONGJMP_CHK
306 INTERCEPTOR(void, __longjmp_chk, void *env, int val) {
307 __asan_handle_no_return();
308 REAL(__longjmp_chk)(env, val);
310 #endif
312 #if ASAN_INTERCEPT_SIGLONGJMP
313 INTERCEPTOR(void, siglongjmp, void *env, int val) {
314 __asan_handle_no_return();
315 REAL(siglongjmp)(env, val);
317 #endif
319 #if ASAN_INTERCEPT___CXA_THROW
320 INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) {
321 CHECK(REAL(__cxa_throw));
322 __asan_handle_no_return();
323 REAL(__cxa_throw)(a, b, c);
325 #endif
327 #if ASAN_INTERCEPT_INDEX
328 # if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
329 INTERCEPTOR(char*, index, const char *string, int c)
330 ALIAS(WRAPPER_NAME(strchr));
331 # else
332 # if SANITIZER_MAC
333 DECLARE_REAL(char*, index, const char *string, int c)
334 OVERRIDE_FUNCTION(index, strchr);
335 # else
336 DEFINE_REAL(char*, index, const char *string, int c)
337 # endif
338 # endif
339 #endif // ASAN_INTERCEPT_INDEX
341 // For both strcat() and strncat() we need to check the validity of |to|
342 // argument irrespective of the |from| length.
343 INTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT
344 void *ctx;
345 ASAN_INTERCEPTOR_ENTER(ctx, strcat); // NOLINT
346 ENSURE_ASAN_INITED();
347 if (flags()->replace_str) {
348 uptr from_length = REAL(strlen)(from);
349 ASAN_READ_RANGE(ctx, from, from_length + 1);
350 uptr to_length = REAL(strlen)(to);
351 ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);
352 ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
353 // If the copying actually happens, the |from| string should not overlap
354 // with the resulting string starting at |to|, which has a length of
355 // to_length + from_length + 1.
356 if (from_length > 0) {
357 CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1,
358 from, from_length + 1);
361 return REAL(strcat)(to, from); // NOLINT
364 INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) {
365 void *ctx;
366 ASAN_INTERCEPTOR_ENTER(ctx, strncat);
367 ENSURE_ASAN_INITED();
368 if (flags()->replace_str) {
369 uptr from_length = MaybeRealStrnlen(from, size);
370 uptr copy_length = Min(size, from_length + 1);
371 ASAN_READ_RANGE(ctx, from, copy_length);
372 uptr to_length = REAL(strlen)(to);
373 ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);
374 ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
375 if (from_length > 0) {
376 CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1,
377 from, copy_length);
380 return REAL(strncat)(to, from, size);
383 INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT
384 void *ctx;
385 ASAN_INTERCEPTOR_ENTER(ctx, strcpy); // NOLINT
386 #if SANITIZER_MAC
387 if (UNLIKELY(!asan_inited)) return REAL(strcpy)(to, from); // NOLINT
388 #endif
389 // strcpy is called from malloc_default_purgeable_zone()
390 // in __asan::ReplaceSystemAlloc() on Mac.
391 if (asan_init_is_running) {
392 return REAL(strcpy)(to, from); // NOLINT
394 ENSURE_ASAN_INITED();
395 if (flags()->replace_str) {
396 uptr from_size = REAL(strlen)(from) + 1;
397 CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size);
398 ASAN_READ_RANGE(ctx, from, from_size);
399 ASAN_WRITE_RANGE(ctx, to, from_size);
401 return REAL(strcpy)(to, from); // NOLINT
404 INTERCEPTOR(char*, strdup, const char *s) {
405 void *ctx;
406 ASAN_INTERCEPTOR_ENTER(ctx, strdup);
407 if (UNLIKELY(!asan_inited)) return internal_strdup(s);
408 ENSURE_ASAN_INITED();
409 uptr length = REAL(strlen)(s);
410 if (flags()->replace_str) {
411 ASAN_READ_RANGE(ctx, s, length + 1);
413 GET_STACK_TRACE_MALLOC;
414 void *new_mem = asan_malloc(length + 1, &stack);
415 REAL(memcpy)(new_mem, s, length + 1);
416 return reinterpret_cast<char*>(new_mem);
419 #if ASAN_INTERCEPT___STRDUP
420 INTERCEPTOR(char*, __strdup, const char *s) {
421 void *ctx;
422 ASAN_INTERCEPTOR_ENTER(ctx, strdup);
423 if (UNLIKELY(!asan_inited)) return internal_strdup(s);
424 ENSURE_ASAN_INITED();
425 uptr length = REAL(strlen)(s);
426 if (flags()->replace_str) {
427 ASAN_READ_RANGE(ctx, s, length + 1);
429 GET_STACK_TRACE_MALLOC;
430 void *new_mem = asan_malloc(length + 1, &stack);
431 REAL(memcpy)(new_mem, s, length + 1);
432 return reinterpret_cast<char*>(new_mem);
434 #endif // ASAN_INTERCEPT___STRDUP
436 INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) {
437 void *ctx;
438 ASAN_INTERCEPTOR_ENTER(ctx, strncpy);
439 ENSURE_ASAN_INITED();
440 if (flags()->replace_str) {
441 uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1);
442 CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size);
443 ASAN_READ_RANGE(ctx, from, from_size);
444 ASAN_WRITE_RANGE(ctx, to, size);
446 return REAL(strncpy)(to, from, size);
449 INTERCEPTOR(long, strtol, const char *nptr, // NOLINT
450 char **endptr, int base) {
451 void *ctx;
452 ASAN_INTERCEPTOR_ENTER(ctx, strtol);
453 ENSURE_ASAN_INITED();
454 if (!flags()->replace_str) {
455 return REAL(strtol)(nptr, endptr, base);
457 char *real_endptr;
458 long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT
459 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
460 return result;
463 INTERCEPTOR(int, atoi, const char *nptr) {
464 void *ctx;
465 ASAN_INTERCEPTOR_ENTER(ctx, atoi);
466 #if SANITIZER_MAC
467 if (UNLIKELY(!asan_inited)) return REAL(atoi)(nptr);
468 #endif
469 ENSURE_ASAN_INITED();
470 if (!flags()->replace_str) {
471 return REAL(atoi)(nptr);
473 char *real_endptr;
474 // "man atoi" tells that behavior of atoi(nptr) is the same as
475 // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the
476 // parsed integer can't be stored in *long* type (even if it's
477 // different from int). So, we just imitate this behavior.
478 int result = REAL(strtol)(nptr, &real_endptr, 10);
479 FixRealStrtolEndptr(nptr, &real_endptr);
480 ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
481 return result;
484 INTERCEPTOR(long, atol, const char *nptr) { // NOLINT
485 void *ctx;
486 ASAN_INTERCEPTOR_ENTER(ctx, atol);
487 #if SANITIZER_MAC
488 if (UNLIKELY(!asan_inited)) return REAL(atol)(nptr);
489 #endif
490 ENSURE_ASAN_INITED();
491 if (!flags()->replace_str) {
492 return REAL(atol)(nptr);
494 char *real_endptr;
495 long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT
496 FixRealStrtolEndptr(nptr, &real_endptr);
497 ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
498 return result;
501 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
502 INTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT
503 char **endptr, int base) {
504 void *ctx;
505 ASAN_INTERCEPTOR_ENTER(ctx, strtoll);
506 ENSURE_ASAN_INITED();
507 if (!flags()->replace_str) {
508 return REAL(strtoll)(nptr, endptr, base);
510 char *real_endptr;
511 long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT
512 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
513 return result;
516 INTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT
517 void *ctx;
518 ASAN_INTERCEPTOR_ENTER(ctx, atoll);
519 ENSURE_ASAN_INITED();
520 if (!flags()->replace_str) {
521 return REAL(atoll)(nptr);
523 char *real_endptr;
524 long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT
525 FixRealStrtolEndptr(nptr, &real_endptr);
526 ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
527 return result;
529 #endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL
531 #if ASAN_INTERCEPT___CXA_ATEXIT
532 static void AtCxaAtexit(void *unused) {
533 (void)unused;
534 StopInitOrderChecking();
537 INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
538 void *dso_handle) {
539 #if SANITIZER_MAC
540 if (UNLIKELY(!asan_inited)) return REAL(__cxa_atexit)(func, arg, dso_handle);
541 #endif
542 ENSURE_ASAN_INITED();
543 int res = REAL(__cxa_atexit)(func, arg, dso_handle);
544 REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr);
545 return res;
547 #endif // ASAN_INTERCEPT___CXA_ATEXIT
549 #if ASAN_INTERCEPT_FORK
550 INTERCEPTOR(int, fork, void) {
551 ENSURE_ASAN_INITED();
552 int pid = REAL(fork)();
553 return pid;
555 #endif // ASAN_INTERCEPT_FORK
557 // ---------------------- InitializeAsanInterceptors ---------------- {{{1
558 namespace __asan {
559 void InitializeAsanInterceptors() {
560 static bool was_called_once;
561 CHECK(!was_called_once);
562 was_called_once = true;
563 InitializeCommonInterceptors();
564 InitializeSignalInterceptors();
566 // Intercept str* functions.
567 ASAN_INTERCEPT_FUNC(strcat); // NOLINT
568 ASAN_INTERCEPT_FUNC(strcpy); // NOLINT
569 ASAN_INTERCEPT_FUNC(strncat);
570 ASAN_INTERCEPT_FUNC(strncpy);
571 ASAN_INTERCEPT_FUNC(strdup);
572 #if ASAN_INTERCEPT___STRDUP
573 ASAN_INTERCEPT_FUNC(__strdup);
574 #endif
575 #if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
576 ASAN_INTERCEPT_FUNC(index);
577 #endif
579 ASAN_INTERCEPT_FUNC(atoi);
580 ASAN_INTERCEPT_FUNC(atol);
581 ASAN_INTERCEPT_FUNC(strtol);
582 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
583 ASAN_INTERCEPT_FUNC(atoll);
584 ASAN_INTERCEPT_FUNC(strtoll);
585 #endif
587 // Intecept jump-related functions.
588 ASAN_INTERCEPT_FUNC(longjmp);
590 #if ASAN_INTERCEPT_SWAPCONTEXT
591 ASAN_INTERCEPT_FUNC(swapcontext);
592 #endif
593 #if ASAN_INTERCEPT__LONGJMP
594 ASAN_INTERCEPT_FUNC(_longjmp);
595 #endif
596 #if ASAN_INTERCEPT___LONGJMP_CHK
597 ASAN_INTERCEPT_FUNC(__longjmp_chk);
598 #endif
599 #if ASAN_INTERCEPT_SIGLONGJMP
600 ASAN_INTERCEPT_FUNC(siglongjmp);
601 #endif
603 // Intercept exception handling functions.
604 #if ASAN_INTERCEPT___CXA_THROW
605 ASAN_INTERCEPT_FUNC(__cxa_throw);
606 #endif
608 // Intercept threading-related functions
609 #if ASAN_INTERCEPT_PTHREAD_CREATE
610 #if defined(ASAN_PTHREAD_CREATE_VERSION)
611 ASAN_INTERCEPT_FUNC_VER(pthread_create, ASAN_PTHREAD_CREATE_VERSION);
612 #else
613 ASAN_INTERCEPT_FUNC(pthread_create);
614 #endif
615 ASAN_INTERCEPT_FUNC(pthread_join);
616 #endif
618 // Intercept atexit function.
619 #if ASAN_INTERCEPT___CXA_ATEXIT
620 ASAN_INTERCEPT_FUNC(__cxa_atexit);
621 #endif
623 #if ASAN_INTERCEPT_FORK
624 ASAN_INTERCEPT_FUNC(fork);
625 #endif
627 InitializePlatformInterceptors();
629 VReport(1, "AddressSanitizer: libc interceptors initialized\n");
632 } // namespace __asan
634 #endif // !SANITIZER_FUCHSIA