]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/asan/asan_interceptors.cc
Merge ACPICA 20150619.
[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 #include "asan_interceptors.h"
15
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 "sanitizer_common/sanitizer_libc.h"
25
26 namespace __asan {
27
28 // Return true if we can quickly decide that the region is unpoisoned.
29 static inline bool QuickCheckForUnpoisonedRegion(uptr beg, uptr size) {
30   if (size == 0) return true;
31   if (size <= 32)
32     return !AddressIsPoisoned(beg) &&
33            !AddressIsPoisoned(beg + size - 1) &&
34            !AddressIsPoisoned(beg + size / 2);
35   return false;
36 }
37
38 struct AsanInterceptorContext {
39   const char *interceptor_name;
40 };
41
42 // We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,
43 // and ASAN_WRITE_RANGE as macro instead of function so
44 // that no extra frames are created, and stack trace contains
45 // relevant information only.
46 // We check all shadow bytes.
47 #define ACCESS_MEMORY_RANGE(ctx, offset, size, isWrite) do {            \
48     uptr __offset = (uptr)(offset);                                     \
49     uptr __size = (uptr)(size);                                         \
50     uptr __bad = 0;                                                     \
51     if (__offset > __offset + __size) {                                 \
52       GET_STACK_TRACE_FATAL_HERE;                                       \
53       ReportStringFunctionSizeOverflow(__offset, __size, &stack);       \
54     }                                                                   \
55     if (!QuickCheckForUnpoisonedRegion(__offset, __size) &&             \
56         (__bad = __asan_region_is_poisoned(__offset, __size))) {        \
57       AsanInterceptorContext *_ctx = (AsanInterceptorContext *)ctx;     \
58       bool suppressed = false;                                          \
59       if (_ctx) {                                                       \
60         suppressed = IsInterceptorSuppressed(_ctx->interceptor_name);   \
61         if (!suppressed && HaveStackTraceBasedSuppressions()) {         \
62           GET_STACK_TRACE_FATAL_HERE;                                   \
63           suppressed = IsStackTraceSuppressed(&stack);                  \
64         }                                                               \
65       }                                                                 \
66       if (!suppressed) {                                                \
67         GET_CURRENT_PC_BP_SP;                                           \
68         __asan_report_error(pc, bp, sp, __bad, isWrite, __size);        \
69       }                                                                 \
70     }                                                                   \
71   } while (0)
72
73 #define ASAN_READ_RANGE(ctx, offset, size) \
74   ACCESS_MEMORY_RANGE(ctx, offset, size, false)
75 #define ASAN_WRITE_RANGE(ctx, offset, size) \
76   ACCESS_MEMORY_RANGE(ctx, offset, size, true)
77
78 // Behavior of functions like "memcpy" or "strcpy" is undefined
79 // if memory intervals overlap. We report error in this case.
80 // Macro is used to avoid creation of new frames.
81 static inline bool RangesOverlap(const char *offset1, uptr length1,
82                                  const char *offset2, uptr length2) {
83   return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1));
84 }
85 #define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \
86   const char *offset1 = (const char*)_offset1; \
87   const char *offset2 = (const char*)_offset2; \
88   if (RangesOverlap(offset1, length1, offset2, length2)) { \
89     GET_STACK_TRACE_FATAL_HERE; \
90     ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \
91                                             offset2, length2, &stack); \
92   } \
93 } while (0)
94
95 static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
96 #if ASAN_INTERCEPT_STRNLEN
97   if (REAL(strnlen) != 0) {
98     return REAL(strnlen)(s, maxlen);
99   }
100 #endif
101   return internal_strnlen(s, maxlen);
102 }
103
104 void SetThreadName(const char *name) {
105   AsanThread *t = GetCurrentThread();
106   if (t)
107     asanThreadRegistry().SetThreadName(t->tid(), name);
108 }
109
110 int OnExit() {
111   // FIXME: ask frontend whether we need to return failure.
112   return 0;
113 }
114
115 }  // namespace __asan
116
117 // ---------------------- Wrappers ---------------- {{{1
118 using namespace __asan;  // NOLINT
119
120 DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr)
121 DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
122
123 #if !SANITIZER_MAC
124 #define ASAN_INTERCEPT_FUNC(name)                                        \
125   do {                                                                   \
126     if ((!INTERCEPT_FUNCTION(name) || !REAL(name)))                      \
127       VReport(1, "AddressSanitizer: failed to intercept '" #name "'\n"); \
128   } while (0)
129 #else
130 // OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION.
131 #define ASAN_INTERCEPT_FUNC(name)
132 #endif  // SANITIZER_MAC
133
134 #define ASAN_INTERCEPTOR_ENTER(ctx, func)                                      \
135   AsanInterceptorContext _ctx = {#func};                                       \
136   ctx = (void *)&_ctx;                                                         \
137   (void) ctx;                                                                  \
138
139 #define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name)
140 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
141   ASAN_WRITE_RANGE(ctx, ptr, size)
142 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
143   ASAN_READ_RANGE(ctx, ptr, size)
144 #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)                               \
145   ASAN_INTERCEPTOR_ENTER(ctx, func);                                           \
146   do {                                                                         \
147     if (asan_init_is_running)                                                  \
148       return REAL(func)(__VA_ARGS__);                                          \
149     if (SANITIZER_MAC && UNLIKELY(!asan_inited))                               \
150       return REAL(func)(__VA_ARGS__);                                          \
151     ENSURE_ASAN_INITED();                                                      \
152   } while (false)
153 #define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \
154   do {                                            \
155   } while (false)
156 #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
157   do {                                         \
158   } while (false)
159 #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
160   do {                                         \
161   } while (false)
162 #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
163   do {                                                      \
164   } while (false)
165 #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name)
166 // Should be asanThreadRegistry().SetThreadNameByUserId(thread, name)
167 // But asan does not remember UserId's for threads (pthread_t);
168 // and remembers all ever existed threads, so the linear search by UserId
169 // can be slow.
170 #define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
171   do {                                                         \
172   } while (false)
173 #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
174 #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
175 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \
176   CoverageUpdateMapping()
177 #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() CoverageUpdateMapping()
178 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!asan_inited)
179 #include "sanitizer_common/sanitizer_common_interceptors.inc"
180
181 // Syscall interceptors don't have contexts, we don't support suppressions
182 // for them.
183 #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(nullptr, p, s)
184 #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(nullptr, p, s)
185 #define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
186   do {                                       \
187     (void)(p);                               \
188     (void)(s);                               \
189   } while (false)
190 #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \
191   do {                                        \
192     (void)(p);                                \
193     (void)(s);                                \
194   } while (false)
195 #include "sanitizer_common/sanitizer_common_syscalls.inc"
196
197 struct ThreadStartParam {
198   atomic_uintptr_t t;
199   atomic_uintptr_t is_registered;
200 };
201
202 static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
203 #if SANITIZER_WINDOWS
204   // FIXME: this is a bandaid fix for PR22025.
205   AsanThread *t = (AsanThread*)arg;
206   SetCurrentThread(t);
207   return t->ThreadStart(GetTid(), /* signal_thread_is_registered */ nullptr);
208 #else
209   ThreadStartParam *param = reinterpret_cast<ThreadStartParam *>(arg);
210   AsanThread *t = nullptr;
211   while ((t = reinterpret_cast<AsanThread *>(
212               atomic_load(&param->t, memory_order_acquire))) == 0)
213     internal_sched_yield();
214   SetCurrentThread(t);
215   return t->ThreadStart(GetTid(), &param->is_registered);
216 #endif
217 }
218
219 #if ASAN_INTERCEPT_PTHREAD_CREATE
220 INTERCEPTOR(int, pthread_create, void *thread,
221     void *attr, void *(*start_routine)(void*), void *arg) {
222   EnsureMainThreadIDIsCorrect();
223   // Strict init-order checking is thread-hostile.
224   if (flags()->strict_init_order)
225     StopInitOrderChecking();
226   GET_STACK_TRACE_THREAD;
227   int detached = 0;
228   if (attr != 0)
229     REAL(pthread_attr_getdetachstate)(attr, &detached);
230   ThreadStartParam param;
231   atomic_store(&param.t, 0, memory_order_relaxed);
232   atomic_store(&param.is_registered, 0, memory_order_relaxed);
233   int result = REAL(pthread_create)(thread, attr, asan_thread_start, &param);
234   if (result == 0) {
235     u32 current_tid = GetCurrentTidOrInvalid();
236     AsanThread *t =
237         AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
238     atomic_store(&param.t, reinterpret_cast<uptr>(t), memory_order_release);
239     // Wait until the AsanThread object is initialized and the ThreadRegistry
240     // entry is in "started" state. One reason for this is that after this
241     // interceptor exits, the child thread's stack may be the only thing holding
242     // the |arg| pointer. This may cause LSan to report a leak if leak checking
243     // happens at a point when the interceptor has already exited, but the stack
244     // range for the child thread is not yet known.
245     while (atomic_load(&param.is_registered, memory_order_acquire) == 0)
246       internal_sched_yield();
247   }
248   return result;
249 }
250
251 INTERCEPTOR(int, pthread_join, void *t, void **arg) {
252   return real_pthread_join(t, arg);
253 }
254
255 DEFINE_REAL_PTHREAD_FUNCTIONS
256 #endif  // ASAN_INTERCEPT_PTHREAD_CREATE
257
258 #if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
259
260 #if SANITIZER_ANDROID
261 INTERCEPTOR(void*, bsd_signal, int signum, void *handler) {
262   if (!IsDeadlySignal(signum) || common_flags()->allow_user_segv_handler) {
263     return REAL(bsd_signal)(signum, handler);
264   }
265   return 0;
266 }
267 #else
268 INTERCEPTOR(void*, signal, int signum, void *handler) {
269   if (!IsDeadlySignal(signum) || common_flags()->allow_user_segv_handler) {
270     return REAL(signal)(signum, handler);
271   }
272   return 0;
273 }
274 #endif
275
276 INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
277                             struct sigaction *oldact) {
278   if (!IsDeadlySignal(signum) || common_flags()->allow_user_segv_handler) {
279     return REAL(sigaction)(signum, act, oldact);
280   }
281   return 0;
282 }
283
284 namespace __sanitizer {
285 int real_sigaction(int signum, const void *act, void *oldact) {
286   return REAL(sigaction)(signum, (const struct sigaction *)act,
287                          (struct sigaction *)oldact);
288 }
289 }  // namespace __sanitizer
290
291 #elif SANITIZER_POSIX
292 // We need to have defined REAL(sigaction) on posix systems.
293 DEFINE_REAL(int, sigaction, int signum, const struct sigaction *act,
294     struct sigaction *oldact)
295 #endif  // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
296
297 #if ASAN_INTERCEPT_SWAPCONTEXT
298 static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) {
299   // Align to page size.
300   uptr PageSize = GetPageSizeCached();
301   uptr bottom = stack & ~(PageSize - 1);
302   ssize += stack - bottom;
303   ssize = RoundUpTo(ssize, PageSize);
304   static const uptr kMaxSaneContextStackSize = 1 << 22;  // 4 Mb
305   if (ssize && ssize <= kMaxSaneContextStackSize) {
306     PoisonShadow(bottom, ssize, 0);
307   }
308 }
309
310 INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp,
311             struct ucontext_t *ucp) {
312   static bool reported_warning = false;
313   if (!reported_warning) {
314     Report("WARNING: ASan doesn't fully support makecontext/swapcontext "
315            "functions and may produce false positives in some cases!\n");
316     reported_warning = true;
317   }
318   // Clear shadow memory for new context (it may share stack
319   // with current context).
320   uptr stack, ssize;
321   ReadContextStack(ucp, &stack, &ssize);
322   ClearShadowMemoryForContextStack(stack, ssize);
323   int res = REAL(swapcontext)(oucp, ucp);
324   // swapcontext technically does not return, but program may swap context to
325   // "oucp" later, that would look as if swapcontext() returned 0.
326   // We need to clear shadow for ucp once again, as it may be in arbitrary
327   // state.
328   ClearShadowMemoryForContextStack(stack, ssize);
329   return res;
330 }
331 #endif  // ASAN_INTERCEPT_SWAPCONTEXT
332
333 INTERCEPTOR(void, longjmp, void *env, int val) {
334   __asan_handle_no_return();
335   REAL(longjmp)(env, val);
336 }
337
338 #if ASAN_INTERCEPT__LONGJMP
339 INTERCEPTOR(void, _longjmp, void *env, int val) {
340   __asan_handle_no_return();
341   REAL(_longjmp)(env, val);
342 }
343 #endif
344
345 #if ASAN_INTERCEPT_SIGLONGJMP
346 INTERCEPTOR(void, siglongjmp, void *env, int val) {
347   __asan_handle_no_return();
348   REAL(siglongjmp)(env, val);
349 }
350 #endif
351
352 #if ASAN_INTERCEPT___CXA_THROW
353 INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) {
354   CHECK(REAL(__cxa_throw));
355   __asan_handle_no_return();
356   REAL(__cxa_throw)(a, b, c);
357 }
358 #endif
359
360 #if SANITIZER_WINDOWS
361 INTERCEPTOR_WINAPI(void, RaiseException, void *a, void *b, void *c, void *d) {
362   CHECK(REAL(RaiseException));
363   __asan_handle_no_return();
364   REAL(RaiseException)(a, b, c, d);
365 }
366
367 INTERCEPTOR(int, _except_handler3, void *a, void *b, void *c, void *d) {
368   CHECK(REAL(_except_handler3));
369   __asan_handle_no_return();
370   return REAL(_except_handler3)(a, b, c, d);
371 }
372
373 #if ASAN_DYNAMIC
374 // This handler is named differently in -MT and -MD CRTs.
375 #define _except_handler4 _except_handler4_common
376 #endif
377 INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
378   CHECK(REAL(_except_handler4));
379   __asan_handle_no_return();
380   return REAL(_except_handler4)(a, b, c, d);
381 }
382 #endif
383
384 static inline int CharCmp(unsigned char c1, unsigned char c2) {
385   return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
386 }
387
388 INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
389   void *ctx;
390   ASAN_INTERCEPTOR_ENTER(ctx, memcmp);
391   if (UNLIKELY(!asan_inited)) return internal_memcmp(a1, a2, size);
392   ENSURE_ASAN_INITED();
393   if (flags()->replace_intrin) {
394     if (flags()->strict_memcmp) {
395       // Check the entire regions even if the first bytes of the buffers are
396       // different.
397       ASAN_READ_RANGE(ctx, a1, size);
398       ASAN_READ_RANGE(ctx, a2, size);
399       // Fallthrough to REAL(memcmp) below.
400     } else {
401       unsigned char c1 = 0, c2 = 0;
402       const unsigned char *s1 = (const unsigned char*)a1;
403       const unsigned char *s2 = (const unsigned char*)a2;
404       uptr i;
405       for (i = 0; i < size; i++) {
406         c1 = s1[i];
407         c2 = s2[i];
408         if (c1 != c2) break;
409       }
410       ASAN_READ_RANGE(ctx, s1, Min(i + 1, size));
411       ASAN_READ_RANGE(ctx, s2, Min(i + 1, size));
412       return CharCmp(c1, c2);
413     }
414   }
415   return REAL(memcmp(a1, a2, size));
416 }
417
418 // memcpy is called during __asan_init() from the internals of printf(...).
419 // We do not treat memcpy with to==from as a bug.
420 // See http://llvm.org/bugs/show_bug.cgi?id=11763.
421 #define ASAN_MEMCPY_IMPL(ctx, to, from, size) do {                             \
422     if (UNLIKELY(!asan_inited)) return internal_memcpy(to, from, size);        \
423     if (asan_init_is_running) {                                                \
424       return REAL(memcpy)(to, from, size);                                     \
425     }                                                                          \
426     ENSURE_ASAN_INITED();                                                      \
427     if (flags()->replace_intrin) {                                             \
428       if (to != from) {                                                        \
429         CHECK_RANGES_OVERLAP("memcpy", to, size, from, size);                  \
430       }                                                                        \
431       ASAN_READ_RANGE(ctx, from, size);                                        \
432       ASAN_WRITE_RANGE(ctx, to, size);                                         \
433     }                                                                          \
434     return REAL(memcpy)(to, from, size);                                       \
435   } while (0)
436
437
438 void *__asan_memcpy(void *to, const void *from, uptr size) {
439   ASAN_MEMCPY_IMPL(nullptr, to, from, size);
440 }
441
442 // memset is called inside Printf.
443 #define ASAN_MEMSET_IMPL(ctx, block, c, size) do {                             \
444     if (UNLIKELY(!asan_inited)) return internal_memset(block, c, size);        \
445     if (asan_init_is_running) {                                                \
446       return REAL(memset)(block, c, size);                                     \
447     }                                                                          \
448     ENSURE_ASAN_INITED();                                                      \
449     if (flags()->replace_intrin) {                                             \
450       ASAN_WRITE_RANGE(ctx, block, size);                                      \
451     }                                                                          \
452     return REAL(memset)(block, c, size);                                       \
453   } while (0)
454
455 void *__asan_memset(void *block, int c, uptr size) {
456   ASAN_MEMSET_IMPL(nullptr, block, c, size);
457 }
458
459 #define ASAN_MEMMOVE_IMPL(ctx, to, from, size) do {                            \
460     if (UNLIKELY(!asan_inited))                                                \
461       return internal_memmove(to, from, size);                                 \
462     ENSURE_ASAN_INITED();                                                      \
463     if (flags()->replace_intrin) {                                             \
464       ASAN_READ_RANGE(ctx, from, size);                                        \
465       ASAN_WRITE_RANGE(ctx, to, size);                                         \
466     }                                                                          \
467     return internal_memmove(to, from, size);                                   \
468   } while (0)
469
470 void *__asan_memmove(void *to, const void *from, uptr size) {
471   ASAN_MEMMOVE_IMPL(nullptr, to, from, size);
472 }
473
474 INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) {
475   void *ctx;
476   ASAN_INTERCEPTOR_ENTER(ctx, memmove);
477   ASAN_MEMMOVE_IMPL(ctx, to, from, size);
478 }
479
480 INTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) {
481   void *ctx;
482   ASAN_INTERCEPTOR_ENTER(ctx, memcpy);
483 #if !SANITIZER_MAC
484   ASAN_MEMCPY_IMPL(ctx, to, from, size);
485 #else
486   // At least on 10.7 and 10.8 both memcpy() and memmove() are being replaced
487   // with WRAP(memcpy). As a result, false positives are reported for memmove()
488   // calls. If we just disable error reporting with
489   // ASAN_OPTIONS=replace_intrin=0, memmove() is still replaced with
490   // internal_memcpy(), which may lead to crashes, see
491   // http://llvm.org/bugs/show_bug.cgi?id=16362.
492   ASAN_MEMMOVE_IMPL(ctx, to, from, size);
493 #endif  // !SANITIZER_MAC
494 }
495
496 INTERCEPTOR(void*, memset, void *block, int c, uptr size) {
497   void *ctx;
498   ASAN_INTERCEPTOR_ENTER(ctx, memset);
499   ASAN_MEMSET_IMPL(ctx, block, c, size);
500 }
501
502 INTERCEPTOR(char*, strchr, const char *str, int c) {
503   void *ctx;
504   ASAN_INTERCEPTOR_ENTER(ctx, strchr);
505   if (UNLIKELY(!asan_inited)) return internal_strchr(str, c);
506   // strchr is called inside create_purgeable_zone() when MallocGuardEdges=1 is
507   // used.
508   if (asan_init_is_running) {
509     return REAL(strchr)(str, c);
510   }
511   ENSURE_ASAN_INITED();
512   char *result = REAL(strchr)(str, c);
513   if (flags()->replace_str) {
514     uptr bytes_read = (result ? result - str : REAL(strlen)(str)) + 1;
515     ASAN_READ_RANGE(ctx, str, bytes_read);
516   }
517   return result;
518 }
519
520 #if ASAN_INTERCEPT_INDEX
521 # if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
522 INTERCEPTOR(char*, index, const char *string, int c)
523   ALIAS(WRAPPER_NAME(strchr));
524 # else
525 #  if SANITIZER_MAC
526 DECLARE_REAL(char*, index, const char *string, int c)
527 OVERRIDE_FUNCTION(index, strchr);
528 #  else
529 DEFINE_REAL(char*, index, const char *string, int c)
530 #  endif
531 # endif
532 #endif  // ASAN_INTERCEPT_INDEX
533
534 // For both strcat() and strncat() we need to check the validity of |to|
535 // argument irrespective of the |from| length.
536 INTERCEPTOR(char*, strcat, char *to, const char *from) {  // NOLINT
537   void *ctx;
538   ASAN_INTERCEPTOR_ENTER(ctx, strcat);  // NOLINT
539   ENSURE_ASAN_INITED();
540   if (flags()->replace_str) {
541     uptr from_length = REAL(strlen)(from);
542     ASAN_READ_RANGE(ctx, from, from_length + 1);
543     uptr to_length = REAL(strlen)(to);
544     ASAN_READ_RANGE(ctx, to, to_length);
545     ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
546     // If the copying actually happens, the |from| string should not overlap
547     // with the resulting string starting at |to|, which has a length of
548     // to_length + from_length + 1.
549     if (from_length > 0) {
550       CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1,
551                            from, from_length + 1);
552     }
553   }
554   return REAL(strcat)(to, from);  // NOLINT
555 }
556
557 INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) {
558   void *ctx;
559   ASAN_INTERCEPTOR_ENTER(ctx, strncat);
560   ENSURE_ASAN_INITED();
561   if (flags()->replace_str) {
562     uptr from_length = MaybeRealStrnlen(from, size);
563     uptr copy_length = Min(size, from_length + 1);
564     ASAN_READ_RANGE(ctx, from, copy_length);
565     uptr to_length = REAL(strlen)(to);
566     ASAN_READ_RANGE(ctx, to, to_length);
567     ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
568     if (from_length > 0) {
569       CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1,
570                            from, copy_length);
571     }
572   }
573   return REAL(strncat)(to, from, size);
574 }
575
576 INTERCEPTOR(char*, strcpy, char *to, const char *from) {  // NOLINT
577   void *ctx;
578   ASAN_INTERCEPTOR_ENTER(ctx, strcpy);  // NOLINT
579 #if SANITIZER_MAC
580   if (UNLIKELY(!asan_inited)) return REAL(strcpy)(to, from);  // NOLINT
581 #endif
582   // strcpy is called from malloc_default_purgeable_zone()
583   // in __asan::ReplaceSystemAlloc() on Mac.
584   if (asan_init_is_running) {
585     return REAL(strcpy)(to, from);  // NOLINT
586   }
587   ENSURE_ASAN_INITED();
588   if (flags()->replace_str) {
589     uptr from_size = REAL(strlen)(from) + 1;
590     CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size);
591     ASAN_READ_RANGE(ctx, from, from_size);
592     ASAN_WRITE_RANGE(ctx, to, from_size);
593   }
594   return REAL(strcpy)(to, from);  // NOLINT
595 }
596
597 #if ASAN_INTERCEPT_STRDUP
598 INTERCEPTOR(char*, strdup, const char *s) {
599   void *ctx;
600   ASAN_INTERCEPTOR_ENTER(ctx, strdup);
601   if (UNLIKELY(!asan_inited)) return internal_strdup(s);
602   ENSURE_ASAN_INITED();
603   uptr length = REAL(strlen)(s);
604   if (flags()->replace_str) {
605     ASAN_READ_RANGE(ctx, s, length + 1);
606   }
607   GET_STACK_TRACE_MALLOC;
608   void *new_mem = asan_malloc(length + 1, &stack);
609   REAL(memcpy)(new_mem, s, length + 1);
610   return reinterpret_cast<char*>(new_mem);
611 }
612 #endif
613
614 INTERCEPTOR(SIZE_T, strlen, const char *s) {
615   void *ctx;
616   ASAN_INTERCEPTOR_ENTER(ctx, strlen);
617   if (UNLIKELY(!asan_inited)) return internal_strlen(s);
618   // strlen is called from malloc_default_purgeable_zone()
619   // in __asan::ReplaceSystemAlloc() on Mac.
620   if (asan_init_is_running) {
621     return REAL(strlen)(s);
622   }
623   ENSURE_ASAN_INITED();
624   SIZE_T length = REAL(strlen)(s);
625   if (flags()->replace_str) {
626     ASAN_READ_RANGE(ctx, s, length + 1);
627   }
628   return length;
629 }
630
631 INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
632   void *ctx;
633   ASAN_INTERCEPTOR_ENTER(ctx, wcslen);
634   SIZE_T length = REAL(wcslen)(s);
635   if (!asan_init_is_running) {
636     ENSURE_ASAN_INITED();
637     ASAN_READ_RANGE(ctx, s, (length + 1) * sizeof(wchar_t));
638   }
639   return length;
640 }
641
642 INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) {
643   void *ctx;
644   ASAN_INTERCEPTOR_ENTER(ctx, strncpy);
645   ENSURE_ASAN_INITED();
646   if (flags()->replace_str) {
647     uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1);
648     CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size);
649     ASAN_READ_RANGE(ctx, from, from_size);
650     ASAN_WRITE_RANGE(ctx, to, size);
651   }
652   return REAL(strncpy)(to, from, size);
653 }
654
655 #if ASAN_INTERCEPT_STRNLEN
656 INTERCEPTOR(uptr, strnlen, const char *s, uptr maxlen) {
657   void *ctx;
658   ASAN_INTERCEPTOR_ENTER(ctx, strnlen);
659   ENSURE_ASAN_INITED();
660   uptr length = REAL(strnlen)(s, maxlen);
661   if (flags()->replace_str) {
662     ASAN_READ_RANGE(ctx, s, Min(length + 1, maxlen));
663   }
664   return length;
665 }
666 #endif  // ASAN_INTERCEPT_STRNLEN
667
668 static inline bool IsValidStrtolBase(int base) {
669   return (base == 0) || (2 <= base && base <= 36);
670 }
671
672 static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
673   CHECK(endptr);
674   if (nptr == *endptr) {
675     // No digits were found at strtol call, we need to find out the last
676     // symbol accessed by strtoll on our own.
677     // We get this symbol by skipping leading blanks and optional +/- sign.
678     while (IsSpace(*nptr)) nptr++;
679     if (*nptr == '+' || *nptr == '-') nptr++;
680     *endptr = const_cast<char *>(nptr);
681   }
682   CHECK(*endptr >= nptr);
683 }
684
685 INTERCEPTOR(long, strtol, const char *nptr,  // NOLINT
686             char **endptr, int base) {
687   void *ctx;
688   ASAN_INTERCEPTOR_ENTER(ctx, strtol);
689   ENSURE_ASAN_INITED();
690   if (!flags()->replace_str) {
691     return REAL(strtol)(nptr, endptr, base);
692   }
693   char *real_endptr;
694   long result = REAL(strtol)(nptr, &real_endptr, base);  // NOLINT
695   if (endptr != 0) {
696     *endptr = real_endptr;
697   }
698   if (IsValidStrtolBase(base)) {
699     FixRealStrtolEndptr(nptr, &real_endptr);
700     ASAN_READ_RANGE(ctx, nptr, (real_endptr - nptr) + 1);
701   }
702   return result;
703 }
704
705 INTERCEPTOR(int, atoi, const char *nptr) {
706   void *ctx;
707   ASAN_INTERCEPTOR_ENTER(ctx, atoi);
708 #if SANITIZER_MAC
709   if (UNLIKELY(!asan_inited)) return REAL(atoi)(nptr);
710 #endif
711   ENSURE_ASAN_INITED();
712   if (!flags()->replace_str) {
713     return REAL(atoi)(nptr);
714   }
715   char *real_endptr;
716   // "man atoi" tells that behavior of atoi(nptr) is the same as
717   // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the
718   // parsed integer can't be stored in *long* type (even if it's
719   // different from int). So, we just imitate this behavior.
720   int result = REAL(strtol)(nptr, &real_endptr, 10);
721   FixRealStrtolEndptr(nptr, &real_endptr);
722   ASAN_READ_RANGE(ctx, nptr, (real_endptr - nptr) + 1);
723   return result;
724 }
725
726 INTERCEPTOR(long, atol, const char *nptr) {  // NOLINT
727   void *ctx;
728   ASAN_INTERCEPTOR_ENTER(ctx, atol);
729 #if SANITIZER_MAC
730   if (UNLIKELY(!asan_inited)) return REAL(atol)(nptr);
731 #endif
732   ENSURE_ASAN_INITED();
733   if (!flags()->replace_str) {
734     return REAL(atol)(nptr);
735   }
736   char *real_endptr;
737   long result = REAL(strtol)(nptr, &real_endptr, 10);  // NOLINT
738   FixRealStrtolEndptr(nptr, &real_endptr);
739   ASAN_READ_RANGE(ctx, nptr, (real_endptr - nptr) + 1);
740   return result;
741 }
742
743 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
744 INTERCEPTOR(long long, strtoll, const char *nptr,  // NOLINT
745             char **endptr, int base) {
746   void *ctx;
747   ASAN_INTERCEPTOR_ENTER(ctx, strtoll);
748   ENSURE_ASAN_INITED();
749   if (!flags()->replace_str) {
750     return REAL(strtoll)(nptr, endptr, base);
751   }
752   char *real_endptr;
753   long long result = REAL(strtoll)(nptr, &real_endptr, base);  // NOLINT
754   if (endptr != 0) {
755     *endptr = real_endptr;
756   }
757   // If base has unsupported value, strtoll can exit with EINVAL
758   // without reading any characters. So do additional checks only
759   // if base is valid.
760   if (IsValidStrtolBase(base)) {
761     FixRealStrtolEndptr(nptr, &real_endptr);
762     ASAN_READ_RANGE(ctx, nptr, (real_endptr - nptr) + 1);
763   }
764   return result;
765 }
766
767 INTERCEPTOR(long long, atoll, const char *nptr) {  // NOLINT
768   void *ctx;
769   ASAN_INTERCEPTOR_ENTER(ctx, atoll);
770   ENSURE_ASAN_INITED();
771   if (!flags()->replace_str) {
772     return REAL(atoll)(nptr);
773   }
774   char *real_endptr;
775   long long result = REAL(strtoll)(nptr, &real_endptr, 10);  // NOLINT
776   FixRealStrtolEndptr(nptr, &real_endptr);
777   ASAN_READ_RANGE(ctx, nptr, (real_endptr - nptr) + 1);
778   return result;
779 }
780 #endif  // ASAN_INTERCEPT_ATOLL_AND_STRTOLL
781
782 static void AtCxaAtexit(void *unused) {
783   (void)unused;
784   StopInitOrderChecking();
785 }
786
787 #if ASAN_INTERCEPT___CXA_ATEXIT
788 INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
789             void *dso_handle) {
790 #if SANITIZER_MAC
791   if (UNLIKELY(!asan_inited)) return REAL(__cxa_atexit)(func, arg, dso_handle);
792 #endif
793   ENSURE_ASAN_INITED();
794   int res = REAL(__cxa_atexit)(func, arg, dso_handle);
795   REAL(__cxa_atexit)(AtCxaAtexit, 0, 0);
796   return res;
797 }
798 #endif  // ASAN_INTERCEPT___CXA_ATEXIT
799
800 #if ASAN_INTERCEPT_FORK
801 INTERCEPTOR(int, fork, void) {
802   ENSURE_ASAN_INITED();
803   if (common_flags()->coverage) CovBeforeFork();
804   int pid = REAL(fork)();
805   if (common_flags()->coverage) CovAfterFork(pid);
806   return pid;
807 }
808 #endif  // ASAN_INTERCEPT_FORK
809
810 #if SANITIZER_WINDOWS
811 INTERCEPTOR_WINAPI(DWORD, CreateThread,
812                    void* security, uptr stack_size,
813                    DWORD (__stdcall *start_routine)(void*), void* arg,
814                    DWORD thr_flags, void* tid) {
815   // Strict init-order checking is thread-hostile.
816   if (flags()->strict_init_order)
817     StopInitOrderChecking();
818   GET_STACK_TRACE_THREAD;
819   // FIXME: The CreateThread interceptor is not the same as a pthread_create
820   // one.  This is a bandaid fix for PR22025.
821   bool detached = false;  // FIXME: how can we determine it on Windows?
822   u32 current_tid = GetCurrentTidOrInvalid();
823   AsanThread *t =
824         AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
825   return REAL(CreateThread)(security, stack_size,
826                             asan_thread_start, t, thr_flags, tid);
827 }
828
829 namespace __asan {
830 void InitializeWindowsInterceptors() {
831   ASAN_INTERCEPT_FUNC(CreateThread);
832   ASAN_INTERCEPT_FUNC(RaiseException);
833   ASAN_INTERCEPT_FUNC(_except_handler3);
834   ASAN_INTERCEPT_FUNC(_except_handler4);
835 }
836
837 }  // namespace __asan
838 #endif
839
840 // ---------------------- InitializeAsanInterceptors ---------------- {{{1
841 namespace __asan {
842 void InitializeAsanInterceptors() {
843   static bool was_called_once;
844   CHECK(was_called_once == false);
845   was_called_once = true;
846   InitializeCommonInterceptors();
847
848   // Intercept mem* functions.
849   ASAN_INTERCEPT_FUNC(memcmp);
850   ASAN_INTERCEPT_FUNC(memmove);
851   ASAN_INTERCEPT_FUNC(memset);
852   if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) {
853     ASAN_INTERCEPT_FUNC(memcpy);
854   }
855
856   // Intercept str* functions.
857   ASAN_INTERCEPT_FUNC(strcat);  // NOLINT
858   ASAN_INTERCEPT_FUNC(strchr);
859   ASAN_INTERCEPT_FUNC(strcpy);  // NOLINT
860   ASAN_INTERCEPT_FUNC(strlen);
861   ASAN_INTERCEPT_FUNC(wcslen);
862   ASAN_INTERCEPT_FUNC(strncat);
863   ASAN_INTERCEPT_FUNC(strncpy);
864 #if ASAN_INTERCEPT_STRDUP
865   ASAN_INTERCEPT_FUNC(strdup);
866 #endif
867 #if ASAN_INTERCEPT_STRNLEN
868   ASAN_INTERCEPT_FUNC(strnlen);
869 #endif
870 #if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
871   ASAN_INTERCEPT_FUNC(index);
872 #endif
873
874   ASAN_INTERCEPT_FUNC(atoi);
875   ASAN_INTERCEPT_FUNC(atol);
876   ASAN_INTERCEPT_FUNC(strtol);
877 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
878   ASAN_INTERCEPT_FUNC(atoll);
879   ASAN_INTERCEPT_FUNC(strtoll);
880 #endif
881
882   // Intecept signal- and jump-related functions.
883   ASAN_INTERCEPT_FUNC(longjmp);
884 #if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
885   ASAN_INTERCEPT_FUNC(sigaction);
886 #if SANITIZER_ANDROID
887   ASAN_INTERCEPT_FUNC(bsd_signal);
888 #else
889   ASAN_INTERCEPT_FUNC(signal);
890 #endif
891 #endif
892 #if ASAN_INTERCEPT_SWAPCONTEXT
893   ASAN_INTERCEPT_FUNC(swapcontext);
894 #endif
895 #if ASAN_INTERCEPT__LONGJMP
896   ASAN_INTERCEPT_FUNC(_longjmp);
897 #endif
898 #if ASAN_INTERCEPT_SIGLONGJMP
899   ASAN_INTERCEPT_FUNC(siglongjmp);
900 #endif
901
902   // Intercept exception handling functions.
903 #if ASAN_INTERCEPT___CXA_THROW
904   ASAN_INTERCEPT_FUNC(__cxa_throw);
905 #endif
906
907   // Intercept threading-related functions
908 #if ASAN_INTERCEPT_PTHREAD_CREATE
909   ASAN_INTERCEPT_FUNC(pthread_create);
910   ASAN_INTERCEPT_FUNC(pthread_join);
911 #endif
912
913   // Intercept atexit function.
914 #if ASAN_INTERCEPT___CXA_ATEXIT
915   ASAN_INTERCEPT_FUNC(__cxa_atexit);
916 #endif
917
918 #if ASAN_INTERCEPT_FORK
919   ASAN_INTERCEPT_FUNC(fork);
920 #endif
921
922   // Some Windows-specific interceptors.
923 #if SANITIZER_WINDOWS
924   InitializeWindowsInterceptors();
925 #endif
926
927   VReport(1, "AddressSanitizer: libc interceptors initialized\n");
928 }
929
930 }  // namespace __asan