]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/asan/asan_interceptors.cc
Merge libc++ trunk r300890, and update build glue.
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / asan / asan_interceptors.cc
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 // Intercept various libc functions.
13 //===----------------------------------------------------------------------===//
14
15 #include "asan_interceptors.h"
16 #include "asan_allocator.h"
17 #include "asan_internal.h"
18 #include "asan_mapping.h"
19 #include "asan_poisoning.h"
20 #include "asan_report.h"
21 #include "asan_stack.h"
22 #include "asan_stats.h"
23 #include "asan_suppressions.h"
24 #include "lsan/lsan_common.h"
25 #include "sanitizer_common/sanitizer_libc.h"
26
27 #if SANITIZER_POSIX
28 #include "sanitizer_common/sanitizer_posix.h"
29 #endif
30
31 #if defined(__i386) && SANITIZER_LINUX
32 #define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1"
33 #elif defined(__mips__) && SANITIZER_LINUX
34 #define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.2"
35 #endif
36
37 namespace __asan {
38
39 // Return true if we can quickly decide that the region is unpoisoned.
40 static inline bool QuickCheckForUnpoisonedRegion(uptr beg, uptr size) {
41   if (size == 0) return true;
42   if (size <= 32)
43     return !AddressIsPoisoned(beg) &&
44            !AddressIsPoisoned(beg + size - 1) &&
45            !AddressIsPoisoned(beg + size / 2);
46   return false;
47 }
48
49 struct AsanInterceptorContext {
50   const char *interceptor_name;
51 };
52
53 // We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,
54 // and ASAN_WRITE_RANGE as macro instead of function so
55 // that no extra frames are created, and stack trace contains
56 // relevant information only.
57 // We check all shadow bytes.
58 #define ACCESS_MEMORY_RANGE(ctx, offset, size, isWrite) do {            \
59     uptr __offset = (uptr)(offset);                                     \
60     uptr __size = (uptr)(size);                                         \
61     uptr __bad = 0;                                                     \
62     if (__offset > __offset + __size) {                                 \
63       GET_STACK_TRACE_FATAL_HERE;                                       \
64       ReportStringFunctionSizeOverflow(__offset, __size, &stack);       \
65     }                                                                   \
66     if (!QuickCheckForUnpoisonedRegion(__offset, __size) &&             \
67         (__bad = __asan_region_is_poisoned(__offset, __size))) {        \
68       AsanInterceptorContext *_ctx = (AsanInterceptorContext *)ctx;     \
69       bool suppressed = false;                                          \
70       if (_ctx) {                                                       \
71         suppressed = IsInterceptorSuppressed(_ctx->interceptor_name);   \
72         if (!suppressed && HaveStackTraceBasedSuppressions()) {         \
73           GET_STACK_TRACE_FATAL_HERE;                                   \
74           suppressed = IsStackTraceSuppressed(&stack);                  \
75         }                                                               \
76       }                                                                 \
77       if (!suppressed) {                                                \
78         GET_CURRENT_PC_BP_SP;                                           \
79         ReportGenericError(pc, bp, sp, __bad, isWrite, __size, 0, false);\
80       }                                                                 \
81     }                                                                   \
82   } while (0)
83
84 // memcpy is called during __asan_init() from the internals of printf(...).
85 // We do not treat memcpy with to==from as a bug.
86 // See http://llvm.org/bugs/show_bug.cgi?id=11763.
87 #define ASAN_MEMCPY_IMPL(ctx, to, from, size)                           \
88   do {                                                                  \
89     if (UNLIKELY(!asan_inited)) return internal_memcpy(to, from, size); \
90     if (asan_init_is_running) {                                         \
91       return REAL(memcpy)(to, from, size);                              \
92     }                                                                   \
93     ENSURE_ASAN_INITED();                                               \
94     if (flags()->replace_intrin) {                                      \
95       if (to != from) {                                                 \
96         CHECK_RANGES_OVERLAP("memcpy", to, size, from, size);           \
97       }                                                                 \
98       ASAN_READ_RANGE(ctx, from, size);                                 \
99       ASAN_WRITE_RANGE(ctx, to, size);                                  \
100     }                                                                   \
101     return REAL(memcpy)(to, from, size);                                \
102   } while (0)
103
104 // memset is called inside Printf.
105 #define ASAN_MEMSET_IMPL(ctx, block, c, size)                           \
106   do {                                                                  \
107     if (UNLIKELY(!asan_inited)) return internal_memset(block, c, size); \
108     if (asan_init_is_running) {                                         \
109       return REAL(memset)(block, c, size);                              \
110     }                                                                   \
111     ENSURE_ASAN_INITED();                                               \
112     if (flags()->replace_intrin) {                                      \
113       ASAN_WRITE_RANGE(ctx, block, size);                               \
114     }                                                                   \
115     return REAL(memset)(block, c, size);                                \
116   } while (0)
117
118 #define ASAN_MEMMOVE_IMPL(ctx, to, from, size)                           \
119   do {                                                                   \
120     if (UNLIKELY(!asan_inited)) return internal_memmove(to, from, size); \
121     ENSURE_ASAN_INITED();                                                \
122     if (flags()->replace_intrin) {                                       \
123       ASAN_READ_RANGE(ctx, from, size);                                  \
124       ASAN_WRITE_RANGE(ctx, to, size);                                   \
125     }                                                                    \
126     return internal_memmove(to, from, size);                             \
127   } while (0)
128
129 #define ASAN_READ_RANGE(ctx, offset, size) \
130   ACCESS_MEMORY_RANGE(ctx, offset, size, false)
131 #define ASAN_WRITE_RANGE(ctx, offset, size) \
132   ACCESS_MEMORY_RANGE(ctx, offset, size, true)
133
134 #define ASAN_READ_STRING_OF_LEN(ctx, s, len, n)                 \
135   ASAN_READ_RANGE((ctx), (s),                                   \
136     common_flags()->strict_string_checks ? (len) + 1 : (n))
137
138 #define ASAN_READ_STRING(ctx, s, n)                             \
139   ASAN_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n))
140
141 // Behavior of functions like "memcpy" or "strcpy" is undefined
142 // if memory intervals overlap. We report error in this case.
143 // Macro is used to avoid creation of new frames.
144 static inline bool RangesOverlap(const char *offset1, uptr length1,
145                                  const char *offset2, uptr length2) {
146   return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1));
147 }
148 #define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \
149   const char *offset1 = (const char*)_offset1; \
150   const char *offset2 = (const char*)_offset2; \
151   if (RangesOverlap(offset1, length1, offset2, length2)) { \
152     GET_STACK_TRACE_FATAL_HERE; \
153     ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \
154                                             offset2, length2, &stack); \
155   } \
156 } while (0)
157
158 static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
159 #if SANITIZER_INTERCEPT_STRNLEN
160   if (REAL(strnlen)) {
161     return REAL(strnlen)(s, maxlen);
162   }
163 #endif
164   return internal_strnlen(s, maxlen);
165 }
166
167 void SetThreadName(const char *name) {
168   AsanThread *t = GetCurrentThread();
169   if (t)
170     asanThreadRegistry().SetThreadName(t->tid(), name);
171 }
172
173 int OnExit() {
174   // FIXME: ask frontend whether we need to return failure.
175   return 0;
176 }
177
178 } // namespace __asan
179
180 // ---------------------- Wrappers ---------------- {{{1
181 using namespace __asan;  // NOLINT
182
183 DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr)
184 DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
185
186 #define ASAN_INTERCEPTOR_ENTER(ctx, func)                                      \
187   AsanInterceptorContext _ctx = {#func};                                       \
188   ctx = (void *)&_ctx;                                                         \
189   (void) ctx;                                                                  \
190
191 #define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name)
192 #define COMMON_INTERCEPT_FUNCTION_VER(name, ver)                          \
193   ASAN_INTERCEPT_FUNC_VER(name, ver)
194 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
195   ASAN_WRITE_RANGE(ctx, ptr, size)
196 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
197   ASAN_READ_RANGE(ctx, ptr, size)
198 #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)                               \
199   ASAN_INTERCEPTOR_ENTER(ctx, func);                                           \
200   do {                                                                         \
201     if (asan_init_is_running)                                                  \
202       return REAL(func)(__VA_ARGS__);                                          \
203     if (SANITIZER_MAC && UNLIKELY(!asan_inited))                               \
204       return REAL(func)(__VA_ARGS__);                                          \
205     ENSURE_ASAN_INITED();                                                      \
206   } while (false)
207 #define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \
208   do {                                            \
209   } while (false)
210 #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
211   do {                                         \
212   } while (false)
213 #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
214   do {                                         \
215   } while (false)
216 #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
217   do {                                                      \
218   } while (false)
219 #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name)
220 // Should be asanThreadRegistry().SetThreadNameByUserId(thread, name)
221 // But asan does not remember UserId's for threads (pthread_t);
222 // and remembers all ever existed threads, so the linear search by UserId
223 // can be slow.
224 #define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
225   do {                                                         \
226   } while (false)
227 #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
228 // Strict init-order checking is dlopen-hostile:
229 // https://github.com/google/sanitizers/issues/178
230 #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag)                           \
231   do {                                                                         \
232     if (flags()->strict_init_order)                                            \
233       StopInitOrderChecking();                                                 \
234     CheckNoDeepBind(filename, flag);                                           \
235   } while (false)
236 #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
237 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \
238   CoverageUpdateMapping()
239 #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() CoverageUpdateMapping()
240 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!asan_inited)
241 #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end)                           \
242   if (AsanThread *t = GetCurrentThread()) {                                    \
243     *begin = t->tls_begin();                                                   \
244     *end = t->tls_end();                                                       \
245   } else {                                                                     \
246     *begin = *end = 0;                                                         \
247   }
248
249 #define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \
250   do {                                                       \
251     ASAN_INTERCEPTOR_ENTER(ctx, memmove);                    \
252     ASAN_MEMMOVE_IMPL(ctx, to, from, size);                  \
253   } while (false)
254
255 #define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \
256   do {                                                      \
257     ASAN_INTERCEPTOR_ENTER(ctx, memcpy);                    \
258     ASAN_MEMCPY_IMPL(ctx, to, from, size);                  \
259   } while (false)
260
261 #define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \
262   do {                                                      \
263     ASAN_INTERCEPTOR_ENTER(ctx, memset);                    \
264     ASAN_MEMSET_IMPL(ctx, block, c, size);                  \
265   } while (false)
266
267 #include "sanitizer_common/sanitizer_common_interceptors.inc"
268
269 // Syscall interceptors don't have contexts, we don't support suppressions
270 // for them.
271 #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(nullptr, p, s)
272 #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(nullptr, p, s)
273 #define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
274   do {                                       \
275     (void)(p);                               \
276     (void)(s);                               \
277   } while (false)
278 #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \
279   do {                                        \
280     (void)(p);                                \
281     (void)(s);                                \
282   } while (false)
283 #include "sanitizer_common/sanitizer_common_syscalls.inc"
284
285 struct ThreadStartParam {
286   atomic_uintptr_t t;
287   atomic_uintptr_t is_registered;
288 };
289
290 #if ASAN_INTERCEPT_PTHREAD_CREATE
291 static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
292   ThreadStartParam *param = reinterpret_cast<ThreadStartParam *>(arg);
293   AsanThread *t = nullptr;
294   while ((t = reinterpret_cast<AsanThread *>(
295               atomic_load(&param->t, memory_order_acquire))) == nullptr)
296     internal_sched_yield();
297   SetCurrentThread(t);
298   return t->ThreadStart(GetTid(), &param->is_registered);
299 }
300
301 INTERCEPTOR(int, pthread_create, void *thread,
302     void *attr, void *(*start_routine)(void*), void *arg) {
303   EnsureMainThreadIDIsCorrect();
304   // Strict init-order checking is thread-hostile.
305   if (flags()->strict_init_order)
306     StopInitOrderChecking();
307   GET_STACK_TRACE_THREAD;
308   int detached = 0;
309   if (attr)
310     REAL(pthread_attr_getdetachstate)(attr, &detached);
311   ThreadStartParam param;
312   atomic_store(&param.t, 0, memory_order_relaxed);
313   atomic_store(&param.is_registered, 0, memory_order_relaxed);
314   int result;
315   {
316     // Ignore all allocations made by pthread_create: thread stack/TLS may be
317     // stored by pthread for future reuse even after thread destruction, and
318     // the linked list it's stored in doesn't even hold valid pointers to the
319     // objects, the latter are calculated by obscure pointer arithmetic.
320 #if CAN_SANITIZE_LEAKS
321     __lsan::ScopedInterceptorDisabler disabler;
322 #endif
323     result = REAL(pthread_create)(thread, attr, asan_thread_start, &param);
324   }
325   if (result == 0) {
326     u32 current_tid = GetCurrentTidOrInvalid();
327     AsanThread *t =
328         AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
329     atomic_store(&param.t, reinterpret_cast<uptr>(t), memory_order_release);
330     // Wait until the AsanThread object is initialized and the ThreadRegistry
331     // entry is in "started" state. One reason for this is that after this
332     // interceptor exits, the child thread's stack may be the only thing holding
333     // the |arg| pointer. This may cause LSan to report a leak if leak checking
334     // happens at a point when the interceptor has already exited, but the stack
335     // range for the child thread is not yet known.
336     while (atomic_load(&param.is_registered, memory_order_acquire) == 0)
337       internal_sched_yield();
338   }
339   return result;
340 }
341
342 INTERCEPTOR(int, pthread_join, void *t, void **arg) {
343   return real_pthread_join(t, arg);
344 }
345
346 DEFINE_REAL_PTHREAD_FUNCTIONS
347 #endif  // ASAN_INTERCEPT_PTHREAD_CREATE
348
349 #if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
350
351 #if SANITIZER_ANDROID
352 INTERCEPTOR(void*, bsd_signal, int signum, void *handler) {
353   if (!IsHandledDeadlySignal(signum) ||
354       common_flags()->allow_user_segv_handler) {
355     return REAL(bsd_signal)(signum, handler);
356   }
357   return 0;
358 }
359 #endif
360
361 INTERCEPTOR(void*, signal, int signum, void *handler) {
362   if (!IsHandledDeadlySignal(signum) ||
363       common_flags()->allow_user_segv_handler) {
364     return REAL(signal)(signum, handler);
365   }
366   return nullptr;
367 }
368
369 INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
370                             struct sigaction *oldact) {
371   if (!IsHandledDeadlySignal(signum) ||
372       common_flags()->allow_user_segv_handler) {
373     return REAL(sigaction)(signum, act, oldact);
374   }
375   return 0;
376 }
377
378 namespace __sanitizer {
379 int real_sigaction(int signum, const void *act, void *oldact) {
380   return REAL(sigaction)(signum, (const struct sigaction *)act,
381                          (struct sigaction *)oldact);
382 }
383 } // namespace __sanitizer
384
385 #elif SANITIZER_POSIX
386 // We need to have defined REAL(sigaction) on posix systems.
387 DEFINE_REAL(int, sigaction, int signum, const struct sigaction *act,
388     struct sigaction *oldact)
389 #endif  // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
390
391 #if ASAN_INTERCEPT_SWAPCONTEXT
392 static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) {
393   // Align to page size.
394   uptr PageSize = GetPageSizeCached();
395   uptr bottom = stack & ~(PageSize - 1);
396   ssize += stack - bottom;
397   ssize = RoundUpTo(ssize, PageSize);
398   static const uptr kMaxSaneContextStackSize = 1 << 22;  // 4 Mb
399   if (AddrIsInMem(bottom) && ssize && ssize <= kMaxSaneContextStackSize) {
400     PoisonShadow(bottom, ssize, 0);
401   }
402 }
403
404 INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp,
405             struct ucontext_t *ucp) {
406   static bool reported_warning = false;
407   if (!reported_warning) {
408     Report("WARNING: ASan doesn't fully support makecontext/swapcontext "
409            "functions and may produce false positives in some cases!\n");
410     reported_warning = true;
411   }
412   // Clear shadow memory for new context (it may share stack
413   // with current context).
414   uptr stack, ssize;
415   ReadContextStack(ucp, &stack, &ssize);
416   ClearShadowMemoryForContextStack(stack, ssize);
417   int res = REAL(swapcontext)(oucp, ucp);
418   // swapcontext technically does not return, but program may swap context to
419   // "oucp" later, that would look as if swapcontext() returned 0.
420   // We need to clear shadow for ucp once again, as it may be in arbitrary
421   // state.
422   ClearShadowMemoryForContextStack(stack, ssize);
423   return res;
424 }
425 #endif  // ASAN_INTERCEPT_SWAPCONTEXT
426
427 INTERCEPTOR(void, longjmp, void *env, int val) {
428   __asan_handle_no_return();
429   REAL(longjmp)(env, val);
430 }
431
432 #if ASAN_INTERCEPT__LONGJMP
433 INTERCEPTOR(void, _longjmp, void *env, int val) {
434   __asan_handle_no_return();
435   REAL(_longjmp)(env, val);
436 }
437 #endif
438
439 #if ASAN_INTERCEPT_SIGLONGJMP
440 INTERCEPTOR(void, siglongjmp, void *env, int val) {
441   __asan_handle_no_return();
442   REAL(siglongjmp)(env, val);
443 }
444 #endif
445
446 #if ASAN_INTERCEPT___CXA_THROW
447 INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) {
448   CHECK(REAL(__cxa_throw));
449   __asan_handle_no_return();
450   REAL(__cxa_throw)(a, b, c);
451 }
452 #endif
453
454 void *__asan_memcpy(void *to, const void *from, uptr size) {
455   ASAN_MEMCPY_IMPL(nullptr, to, from, size);
456 }
457
458 void *__asan_memset(void *block, int c, uptr size) {
459   ASAN_MEMSET_IMPL(nullptr, block, c, size);
460 }
461
462 void *__asan_memmove(void *to, const void *from, uptr size) {
463   ASAN_MEMMOVE_IMPL(nullptr, to, from, size);
464 }
465
466 #if ASAN_INTERCEPT_INDEX
467 # if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
468 INTERCEPTOR(char*, index, const char *string, int c)
469   ALIAS(WRAPPER_NAME(strchr));
470 # else
471 #  if SANITIZER_MAC
472 DECLARE_REAL(char*, index, const char *string, int c)
473 OVERRIDE_FUNCTION(index, strchr);
474 #  else
475 DEFINE_REAL(char*, index, const char *string, int c)
476 #  endif
477 # endif
478 #endif  // ASAN_INTERCEPT_INDEX
479
480 // For both strcat() and strncat() we need to check the validity of |to|
481 // argument irrespective of the |from| length.
482 INTERCEPTOR(char*, strcat, char *to, const char *from) {  // NOLINT
483   void *ctx;
484   ASAN_INTERCEPTOR_ENTER(ctx, strcat);  // NOLINT
485   ENSURE_ASAN_INITED();
486   if (flags()->replace_str) {
487     uptr from_length = REAL(strlen)(from);
488     ASAN_READ_RANGE(ctx, from, from_length + 1);
489     uptr to_length = REAL(strlen)(to);
490     ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);
491     ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
492     // If the copying actually happens, the |from| string should not overlap
493     // with the resulting string starting at |to|, which has a length of
494     // to_length + from_length + 1.
495     if (from_length > 0) {
496       CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1,
497                            from, from_length + 1);
498     }
499   }
500   return REAL(strcat)(to, from);  // NOLINT
501 }
502
503 INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) {
504   void *ctx;
505   ASAN_INTERCEPTOR_ENTER(ctx, strncat);
506   ENSURE_ASAN_INITED();
507   if (flags()->replace_str) {
508     uptr from_length = MaybeRealStrnlen(from, size);
509     uptr copy_length = Min(size, from_length + 1);
510     ASAN_READ_RANGE(ctx, from, copy_length);
511     uptr to_length = REAL(strlen)(to);
512     ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);
513     ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
514     if (from_length > 0) {
515       CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1,
516                            from, copy_length);
517     }
518   }
519   return REAL(strncat)(to, from, size);
520 }
521
522 INTERCEPTOR(char*, strcpy, char *to, const char *from) {  // NOLINT
523   void *ctx;
524   ASAN_INTERCEPTOR_ENTER(ctx, strcpy);  // NOLINT
525 #if SANITIZER_MAC
526   if (UNLIKELY(!asan_inited)) return REAL(strcpy)(to, from);  // NOLINT
527 #endif
528   // strcpy is called from malloc_default_purgeable_zone()
529   // in __asan::ReplaceSystemAlloc() on Mac.
530   if (asan_init_is_running) {
531     return REAL(strcpy)(to, from);  // NOLINT
532   }
533   ENSURE_ASAN_INITED();
534   if (flags()->replace_str) {
535     uptr from_size = REAL(strlen)(from) + 1;
536     CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size);
537     ASAN_READ_RANGE(ctx, from, from_size);
538     ASAN_WRITE_RANGE(ctx, to, from_size);
539   }
540   return REAL(strcpy)(to, from);  // NOLINT
541 }
542
543 INTERCEPTOR(char*, strdup, const char *s) {
544   void *ctx;
545   ASAN_INTERCEPTOR_ENTER(ctx, strdup);
546   if (UNLIKELY(!asan_inited)) return internal_strdup(s);
547   ENSURE_ASAN_INITED();
548   uptr length = REAL(strlen)(s);
549   if (flags()->replace_str) {
550     ASAN_READ_RANGE(ctx, s, length + 1);
551   }
552   GET_STACK_TRACE_MALLOC;
553   void *new_mem = asan_malloc(length + 1, &stack);
554   REAL(memcpy)(new_mem, s, length + 1);
555   return reinterpret_cast<char*>(new_mem);
556 }
557
558 #if ASAN_INTERCEPT___STRDUP
559 INTERCEPTOR(char*, __strdup, const char *s) {
560   void *ctx;
561   ASAN_INTERCEPTOR_ENTER(ctx, strdup);
562   if (UNLIKELY(!asan_inited)) return internal_strdup(s);
563   ENSURE_ASAN_INITED();
564   uptr length = REAL(strlen)(s);
565   if (flags()->replace_str) {
566     ASAN_READ_RANGE(ctx, s, length + 1);
567   }
568   GET_STACK_TRACE_MALLOC;
569   void *new_mem = asan_malloc(length + 1, &stack);
570   REAL(memcpy)(new_mem, s, length + 1);
571   return reinterpret_cast<char*>(new_mem);
572 }
573 #endif // ASAN_INTERCEPT___STRDUP
574
575 INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
576   void *ctx;
577   ASAN_INTERCEPTOR_ENTER(ctx, wcslen);
578   SIZE_T length = internal_wcslen(s);
579   if (!asan_init_is_running) {
580     ENSURE_ASAN_INITED();
581     ASAN_READ_RANGE(ctx, s, (length + 1) * sizeof(wchar_t));
582   }
583   return length;
584 }
585
586 INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) {
587   void *ctx;
588   ASAN_INTERCEPTOR_ENTER(ctx, strncpy);
589   ENSURE_ASAN_INITED();
590   if (flags()->replace_str) {
591     uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1);
592     CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size);
593     ASAN_READ_RANGE(ctx, from, from_size);
594     ASAN_WRITE_RANGE(ctx, to, size);
595   }
596   return REAL(strncpy)(to, from, size);
597 }
598
599 INTERCEPTOR(long, strtol, const char *nptr,  // NOLINT
600             char **endptr, int base) {
601   void *ctx;
602   ASAN_INTERCEPTOR_ENTER(ctx, strtol);
603   ENSURE_ASAN_INITED();
604   if (!flags()->replace_str) {
605     return REAL(strtol)(nptr, endptr, base);
606   }
607   char *real_endptr;
608   long result = REAL(strtol)(nptr, &real_endptr, base);  // NOLINT
609   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
610   return result;
611 }
612
613 INTERCEPTOR(int, atoi, const char *nptr) {
614   void *ctx;
615   ASAN_INTERCEPTOR_ENTER(ctx, atoi);
616 #if SANITIZER_MAC
617   if (UNLIKELY(!asan_inited)) return REAL(atoi)(nptr);
618 #endif
619   ENSURE_ASAN_INITED();
620   if (!flags()->replace_str) {
621     return REAL(atoi)(nptr);
622   }
623   char *real_endptr;
624   // "man atoi" tells that behavior of atoi(nptr) is the same as
625   // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the
626   // parsed integer can't be stored in *long* type (even if it's
627   // different from int). So, we just imitate this behavior.
628   int result = REAL(strtol)(nptr, &real_endptr, 10);
629   FixRealStrtolEndptr(nptr, &real_endptr);
630   ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
631   return result;
632 }
633
634 INTERCEPTOR(long, atol, const char *nptr) {  // NOLINT
635   void *ctx;
636   ASAN_INTERCEPTOR_ENTER(ctx, atol);
637 #if SANITIZER_MAC
638   if (UNLIKELY(!asan_inited)) return REAL(atol)(nptr);
639 #endif
640   ENSURE_ASAN_INITED();
641   if (!flags()->replace_str) {
642     return REAL(atol)(nptr);
643   }
644   char *real_endptr;
645   long result = REAL(strtol)(nptr, &real_endptr, 10);  // NOLINT
646   FixRealStrtolEndptr(nptr, &real_endptr);
647   ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
648   return result;
649 }
650
651 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
652 INTERCEPTOR(long long, strtoll, const char *nptr,  // NOLINT
653             char **endptr, int base) {
654   void *ctx;
655   ASAN_INTERCEPTOR_ENTER(ctx, strtoll);
656   ENSURE_ASAN_INITED();
657   if (!flags()->replace_str) {
658     return REAL(strtoll)(nptr, endptr, base);
659   }
660   char *real_endptr;
661   long long result = REAL(strtoll)(nptr, &real_endptr, base);  // NOLINT
662   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
663   return result;
664 }
665
666 INTERCEPTOR(long long, atoll, const char *nptr) {  // NOLINT
667   void *ctx;
668   ASAN_INTERCEPTOR_ENTER(ctx, atoll);
669   ENSURE_ASAN_INITED();
670   if (!flags()->replace_str) {
671     return REAL(atoll)(nptr);
672   }
673   char *real_endptr;
674   long long result = REAL(strtoll)(nptr, &real_endptr, 10);  // NOLINT
675   FixRealStrtolEndptr(nptr, &real_endptr);
676   ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
677   return result;
678 }
679 #endif  // ASAN_INTERCEPT_ATOLL_AND_STRTOLL
680
681 #if ASAN_INTERCEPT___CXA_ATEXIT
682 static void AtCxaAtexit(void *unused) {
683   (void)unused;
684   StopInitOrderChecking();
685 }
686
687 INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
688             void *dso_handle) {
689 #if SANITIZER_MAC
690   if (UNLIKELY(!asan_inited)) return REAL(__cxa_atexit)(func, arg, dso_handle);
691 #endif
692   ENSURE_ASAN_INITED();
693   int res = REAL(__cxa_atexit)(func, arg, dso_handle);
694   REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr);
695   return res;
696 }
697 #endif  // ASAN_INTERCEPT___CXA_ATEXIT
698
699 #if ASAN_INTERCEPT_FORK
700 INTERCEPTOR(int, fork, void) {
701   ENSURE_ASAN_INITED();
702   if (common_flags()->coverage) CovBeforeFork();
703   int pid = REAL(fork)();
704   if (common_flags()->coverage) CovAfterFork(pid);
705   return pid;
706 }
707 #endif  // ASAN_INTERCEPT_FORK
708
709 // ---------------------- InitializeAsanInterceptors ---------------- {{{1
710 namespace __asan {
711 void InitializeAsanInterceptors() {
712   static bool was_called_once;
713   CHECK(!was_called_once);
714   was_called_once = true;
715   InitializeCommonInterceptors();
716
717   // Intercept str* functions.
718   ASAN_INTERCEPT_FUNC(strcat);  // NOLINT
719   ASAN_INTERCEPT_FUNC(strcpy);  // NOLINT
720   ASAN_INTERCEPT_FUNC(wcslen);
721   ASAN_INTERCEPT_FUNC(strncat);
722   ASAN_INTERCEPT_FUNC(strncpy);
723   ASAN_INTERCEPT_FUNC(strdup);
724 #if ASAN_INTERCEPT___STRDUP
725   ASAN_INTERCEPT_FUNC(__strdup);
726 #endif
727 #if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
728   ASAN_INTERCEPT_FUNC(index);
729 #endif
730
731   ASAN_INTERCEPT_FUNC(atoi);
732   ASAN_INTERCEPT_FUNC(atol);
733   ASAN_INTERCEPT_FUNC(strtol);
734 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
735   ASAN_INTERCEPT_FUNC(atoll);
736   ASAN_INTERCEPT_FUNC(strtoll);
737 #endif
738
739   // Intecept signal- and jump-related functions.
740   ASAN_INTERCEPT_FUNC(longjmp);
741 #if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
742   ASAN_INTERCEPT_FUNC(sigaction);
743 #if SANITIZER_ANDROID
744   ASAN_INTERCEPT_FUNC(bsd_signal);
745 #endif
746   ASAN_INTERCEPT_FUNC(signal);
747 #endif
748 #if ASAN_INTERCEPT_SWAPCONTEXT
749   ASAN_INTERCEPT_FUNC(swapcontext);
750 #endif
751 #if ASAN_INTERCEPT__LONGJMP
752   ASAN_INTERCEPT_FUNC(_longjmp);
753 #endif
754 #if ASAN_INTERCEPT_SIGLONGJMP
755   ASAN_INTERCEPT_FUNC(siglongjmp);
756 #endif
757
758   // Intercept exception handling functions.
759 #if ASAN_INTERCEPT___CXA_THROW
760   ASAN_INTERCEPT_FUNC(__cxa_throw);
761 #endif
762
763   // Intercept threading-related functions
764 #if ASAN_INTERCEPT_PTHREAD_CREATE
765 #if defined(ASAN_PTHREAD_CREATE_VERSION)
766   ASAN_INTERCEPT_FUNC_VER(pthread_create, ASAN_PTHREAD_CREATE_VERSION);
767 #else
768   ASAN_INTERCEPT_FUNC(pthread_create);
769 #endif
770   ASAN_INTERCEPT_FUNC(pthread_join);
771 #endif
772
773   // Intercept atexit function.
774 #if ASAN_INTERCEPT___CXA_ATEXIT
775   ASAN_INTERCEPT_FUNC(__cxa_atexit);
776 #endif
777
778 #if ASAN_INTERCEPT_FORK
779   ASAN_INTERCEPT_FUNC(fork);
780 #endif
781
782   InitializePlatformInterceptors();
783
784   VReport(1, "AddressSanitizer: libc interceptors initialized\n");
785 }
786
787 } // namespace __asan