asan_interceptors.cc revision 4f245442bd9b818cb4c1f5c0d3bcc9fdf1e82f10
1//===-- asan_interceptors.cc ------------------------------------*- C++ -*-===//
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_interface.h"
18#include "asan_internal.h"
19#include "asan_mapping.h"
20#include "asan_stack.h"
21#include "asan_stats.h"
22#include "asan_thread_registry.h"
23#include "interception/interception.h"
24
25#include <new>
26
27// Use macro to describe if specific function should be
28// intercepted on a given platform.
29#define ASAN_INTERCEPT_STRTOLL !defined(_WIN32)
30#define ASAN_INTERCEPT_STRNLEN !defined(__APPLE__)
31
32// Use extern declarations of intercepted functions on Mac and Windows
33// to avoid including system headers.
34#if defined(__APPLE__) || (defined(_WIN32) && !defined(_DLL))
35extern "C" {
36// signal.h
37# if !defined(_WIN32)
38struct sigaction;
39int sigaction(int sig, const struct sigaction *act,
40              struct sigaction *oldact);
41void *signal(int signum, void *handler);
42# endif
43
44// setjmp.h
45void longjmp(void* env, int value);
46# if !defined(_WIN32)
47void _longjmp(void *env, int value);
48# endif
49
50// string.h / strings.h
51int memcmp(const void *a1, const void *a2, size_t size);
52void* memmove(void *to, const void *from, size_t size);
53void* memcpy(void *to, const void *from, size_t size);
54void* memset(void *block, int c, size_t size);
55# if defined(__APPLE__)
56char* strchr(const char *str, int c);
57char* index(const char *string, int c);
58# elif defined(_WIN32)
59char* strchr(const char *s, char c);
60# endif
61char* strcat(char *to, const char* from);  // NOLINT
62char* strcpy(char *to, const char* from);  // NOLINT
63char* strncpy(char *to, const char* from, size_t size);
64int strcmp(const char *s1, const char* s2);
65int strncmp(const char *s1, const char* s2, size_t size);
66# if !defined(_WIN32)
67int strcasecmp(const char *s1, const char *s2);
68int strncasecmp(const char *s1, const char *s2, size_t n);
69char* strdup(const char *s);
70# endif
71size_t strlen(const char *s);
72# if ASAN_INTERCEPT_STRNLEN
73size_t strnlen(const char *s, size_t maxlen);
74# endif
75
76// stdlib.h
77# if ASAN_INTERCEPT_STRTOLL
78long long strtoll(const char *nptr, char **endptr, int base);  // NOLINT
79# endif
80
81// Windows threads.
82# if defined(_WIN32)
83__declspec(dllimport)
84void* __stdcall CreateThread(void *sec, size_t st, void* start,
85                             void *arg, DWORD fl, DWORD *id);
86# endif
87
88// Posix threads.
89# if !defined(_WIN32)
90int pthread_create(void *thread, void *attr, void *(*start_routine)(void*),
91                   void *arg);
92# endif
93}  // extern "C"
94#endif
95
96namespace __asan {
97
98// Instruments read/write access to a single byte in memory.
99// On error calls __asan_report_error, which aborts the program.
100#define ACCESS_ADDRESS(address, isWrite)   do {         \
101  if (AddressIsPoisoned(address)) {                     \
102    GET_CURRENT_PC_BP_SP;                               \
103    __asan_report_error(pc, bp, sp, address, isWrite, /* access_size */ 1); \
104  } \
105} while (0)
106
107// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,
108// and ASAN_WRITE_RANGE as macro instead of function so
109// that no extra frames are created, and stack trace contains
110// relevant information only.
111
112// Instruments read/write access to a memory range.
113// More complex implementation is possible, for now just
114// checking the first and the last byte of a range.
115#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \
116  if (size > 0) { \
117    uintptr_t ptr = (uintptr_t)(offset); \
118    ACCESS_ADDRESS(ptr, isWrite); \
119    ACCESS_ADDRESS(ptr + (size) - 1, isWrite); \
120  } \
121} while (0)
122
123#define ASAN_READ_RANGE(offset, size) do { \
124  ACCESS_MEMORY_RANGE(offset, size, false); \
125} while (0)
126
127#define ASAN_WRITE_RANGE(offset, size) do { \
128  ACCESS_MEMORY_RANGE(offset, size, true); \
129} while (0)
130
131// Behavior of functions like "memcpy" or "strcpy" is undefined
132// if memory intervals overlap. We report error in this case.
133// Macro is used to avoid creation of new frames.
134static inline bool RangesOverlap(const char *offset1, size_t length1,
135                                 const char *offset2, size_t length2) {
136  return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1));
137}
138#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \
139  const char *offset1 = (const char*)_offset1; \
140  const char *offset2 = (const char*)_offset2; \
141  if (RangesOverlap(offset1, length1, offset2, length2)) { \
142    Report("ERROR: AddressSanitizer %s-param-overlap: " \
143           "memory ranges [%p,%p) and [%p, %p) overlap\n", \
144           name, offset1, offset1 + length1, offset2, offset2 + length2); \
145    PRINT_CURRENT_STACK(); \
146    ShowStatsAndAbort(); \
147  } \
148} while (0)
149
150#define ENSURE_ASAN_INITED() do { \
151  CHECK(!asan_init_is_running); \
152  if (!asan_inited) { \
153    __asan_init(); \
154  } \
155} while (0)
156
157static inline bool IsSpace(int c) {
158  return (c == ' ') || (c == '\n') || (c == '\t') ||
159         (c == '\f') || (c == '\r') || (c == '\v');
160}
161
162static inline bool IsDigit(int c) {
163  return (c >= '0') && (c <= '9');
164}
165
166static inline int ToLower(int c) {
167  return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;
168}
169
170// ---------------------- Internal string functions ---------------- {{{1
171
172int64_t internal_simple_strtoll(const char *nptr, char **endptr, int base) {
173  CHECK(base == 10);
174  while (IsSpace(*nptr)) nptr++;
175  int sgn = 1;
176  uint64_t res = 0;
177  bool have_digits = false;
178  char *old_nptr = (char*)nptr;
179  if (*nptr == '+') {
180    sgn = 1;
181    nptr++;
182  } else if (*nptr == '-') {
183    sgn = -1;
184    nptr++;
185  }
186  while (IsDigit(*nptr)) {
187    res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX;
188    int digit = ((*nptr) - '0');
189    res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX;
190    have_digits = true;
191    nptr++;
192  }
193  if (endptr != NULL) {
194    *endptr = (have_digits) ? (char*)nptr : old_nptr;
195  }
196  if (sgn > 0) {
197    return (int64_t)(Min((uint64_t)INT64_MAX, res));
198  } else {
199    return (res > INT64_MAX) ? INT64_MIN : ((int64_t)res * -1);
200  }
201}
202
203int64_t internal_atoll(const char *nptr) {
204  return internal_simple_strtoll(nptr, (char**)NULL, 10);
205}
206
207size_t internal_strlen(const char *s) {
208  size_t i = 0;
209  while (s[i]) i++;
210  return i;
211}
212
213size_t internal_strnlen(const char *s, size_t maxlen) {
214#if ASAN_INTERCEPT_STRNLEN
215  if (REAL(strnlen) != NULL) {
216    return REAL(strnlen)(s, maxlen);
217  }
218#endif
219  size_t i = 0;
220  while (i < maxlen && s[i]) i++;
221  return i;
222}
223
224char* internal_strchr(const char *s, int c) {
225  while (true) {
226    if (*s == (char)c)
227      return (char*)s;
228    if (*s == 0)
229      return NULL;
230    s++;
231  }
232}
233
234void* internal_memchr(const void* s, int c, size_t n) {
235  const char* t = (char*)s;
236  for (size_t i = 0; i < n; ++i, ++t)
237    if (*t == c)
238      return (void*)t;
239  return NULL;
240}
241
242int internal_memcmp(const void* s1, const void* s2, size_t n) {
243  const char* t1 = (char*)s1;
244  const char* t2 = (char*)s2;
245  for (size_t i = 0; i < n; ++i, ++t1, ++t2)
246    if (*t1 != *t2)
247      return *t1 < *t2 ? -1 : 1;
248  return 0;
249}
250
251char *internal_strstr(const char *haystack, const char *needle) {
252  // This is O(N^2), but we are not using it in hot places.
253  size_t len1 = internal_strlen(haystack);
254  size_t len2 = internal_strlen(needle);
255  if (len1 < len2) return 0;
256  for (size_t pos = 0; pos <= len1 - len2; pos++) {
257    if (internal_memcmp(haystack + pos, needle, len2) == 0)
258      return (char*)haystack + pos;
259  }
260  return 0;
261}
262
263char *internal_strncat(char *dst, const char *src, size_t n) {
264  size_t len = internal_strlen(dst);
265  size_t i;
266  for (i = 0; i < n && src[i]; i++)
267    dst[len + i] = src[i];
268  dst[len + i] = 0;
269  return dst;
270}
271
272int internal_strcmp(const char *s1, const char *s2) {
273  while (true) {
274    unsigned c1 = *s1;
275    unsigned c2 = *s2;
276    if (c1 != c2) return (c1 < c2) ? -1 : 1;
277    if (c1 == 0) break;
278    s1++;
279    s2++;
280  }
281  return 0;
282}
283
284char *internal_strncpy(char *dst, const char *src, size_t n) {
285  size_t i;
286  for (i = 0; i < n && src[i]; i++)
287    dst[i] = src[i];
288  return dst;
289}
290
291}  // namespace __asan
292
293// ---------------------- Wrappers ---------------- {{{1
294using namespace __asan;  // NOLINT
295
296#define OPERATOR_NEW_BODY \
297  GET_STACK_TRACE_HERE_FOR_MALLOC;\
298  return asan_memalign(0, size, &stack);
299
300#ifdef ANDROID
301void *operator new(size_t size) { OPERATOR_NEW_BODY; }
302void *operator new[](size_t size) { OPERATOR_NEW_BODY; }
303#else
304void *operator new(size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; }
305void *operator new[](size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; }
306void *operator new(size_t size, std::nothrow_t const&) throw()
307{ OPERATOR_NEW_BODY; }
308void *operator new[](size_t size, std::nothrow_t const&) throw()
309{ OPERATOR_NEW_BODY; }
310#endif
311
312#define OPERATOR_DELETE_BODY \
313  GET_STACK_TRACE_HERE_FOR_FREE(ptr);\
314  asan_free(ptr, &stack);
315
316void operator delete(void *ptr) throw() { OPERATOR_DELETE_BODY; }
317void operator delete[](void *ptr) throw() { OPERATOR_DELETE_BODY; }
318void operator delete(void *ptr, std::nothrow_t const&) throw()
319{ OPERATOR_DELETE_BODY; }
320void operator delete[](void *ptr, std::nothrow_t const&) throw()
321{ OPERATOR_DELETE_BODY;}
322
323static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
324  AsanThread *t = (AsanThread*)arg;
325  asanThreadRegistry().SetCurrent(t);
326  return t->ThreadStart();
327}
328
329#ifndef _WIN32
330INTERCEPTOR(int, pthread_create, void *thread,
331    void *attr, void *(*start_routine)(void*), void *arg) {
332  GET_STACK_TRACE_HERE(kStackTraceMax);
333  int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
334  AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack);
335  asanThreadRegistry().RegisterThread(t);
336  return REAL(pthread_create)(thread, attr, asan_thread_start, t);
337}
338#endif  // !_WIN32
339
340#if !defined(ANDROID) && !defined(_WIN32)
341INTERCEPTOR(void*, signal, int signum, void *handler) {
342  if (!AsanInterceptsSignal(signum)) {
343    return REAL(signal)(signum, handler);
344  }
345  return NULL;
346}
347
348INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
349                            struct sigaction *oldact) {
350  if (!AsanInterceptsSignal(signum)) {
351    return REAL(sigaction)(signum, act, oldact);
352  }
353  return 0;
354}
355#endif  // !ANDROID && !_WIN32
356
357INTERCEPTOR(void, longjmp, void *env, int val) {
358  __asan_handle_no_return();
359  REAL(longjmp)(env, val);
360}
361
362#if !defined(_WIN32)
363INTERCEPTOR(void, _longjmp, void *env, int val) {
364  __asan_handle_no_return();
365  REAL(_longjmp)(env, val);
366}
367
368INTERCEPTOR(void, siglongjmp, void *env, int val) {
369  __asan_handle_no_return();
370  REAL(siglongjmp)(env, val);
371}
372#endif
373
374#if ASAN_HAS_EXCEPTIONS == 1
375#ifdef __APPLE__
376extern "C" void __cxa_throw(void *a, void *b, void *c);
377#endif  // __APPLE__
378
379INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) {
380  CHECK(REAL(__cxa_throw));
381  __asan_handle_no_return();
382  REAL(__cxa_throw)(a, b, c);
383}
384#endif
385
386// intercept mlock and friends.
387// Since asan maps 16T of RAM, mlock is completely unfriendly to asan.
388// All functions return 0 (success).
389static void MlockIsUnsupported() {
390  static bool printed = 0;
391  if (printed) return;
392  printed = true;
393  Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n");
394}
395
396extern "C" {
397INTERCEPTOR_ATTRIBUTE
398int mlock(const void *addr, size_t len) {
399  MlockIsUnsupported();
400  return 0;
401}
402
403INTERCEPTOR_ATTRIBUTE
404int munlock(const void *addr, size_t len) {
405  MlockIsUnsupported();
406  return 0;
407}
408
409INTERCEPTOR_ATTRIBUTE
410int mlockall(int flags) {
411  MlockIsUnsupported();
412  return 0;
413}
414
415INTERCEPTOR_ATTRIBUTE
416int munlockall(void) {
417  MlockIsUnsupported();
418  return 0;
419}
420}  // extern "C"
421
422static inline int CharCmp(unsigned char c1, unsigned char c2) {
423  return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
424}
425
426static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
427  int c1_low = ToLower(c1);
428  int c2_low = ToLower(c2);
429  return c1_low - c2_low;
430}
431
432INTERCEPTOR(int, memcmp, const void *a1, const void *a2, size_t size) {
433  ENSURE_ASAN_INITED();
434  unsigned char c1 = 0, c2 = 0;
435  const unsigned char *s1 = (const unsigned char*)a1;
436  const unsigned char *s2 = (const unsigned char*)a2;
437  size_t i;
438  for (i = 0; i < size; i++) {
439    c1 = s1[i];
440    c2 = s2[i];
441    if (c1 != c2) break;
442  }
443  ASAN_READ_RANGE(s1, Min(i + 1, size));
444  ASAN_READ_RANGE(s2, Min(i + 1, size));
445  return CharCmp(c1, c2);
446}
447
448INTERCEPTOR(void*, memcpy, void *to, const void *from, size_t size) {
449  // memcpy is called during __asan_init() from the internals
450  // of printf(...).
451  if (asan_init_is_running) {
452    return REAL(memcpy)(to, from, size);
453  }
454  ENSURE_ASAN_INITED();
455  if (FLAG_replace_intrin) {
456    if (to != from) {
457      // We do not treat memcpy with to==from as a bug.
458      // See http://llvm.org/bugs/show_bug.cgi?id=11763.
459      CHECK_RANGES_OVERLAP("memcpy", to, size, from, size);
460    }
461    ASAN_WRITE_RANGE(from, size);
462    ASAN_READ_RANGE(to, size);
463  }
464  return REAL(memcpy)(to, from, size);
465}
466
467INTERCEPTOR(void*, memmove, void *to, const void *from, size_t size) {
468  ENSURE_ASAN_INITED();
469  if (FLAG_replace_intrin) {
470    ASAN_WRITE_RANGE(from, size);
471    ASAN_READ_RANGE(to, size);
472  }
473  return REAL(memmove)(to, from, size);
474}
475
476INTERCEPTOR(void*, memset, void *block, int c, size_t size) {
477  // memset is called inside INTERCEPT_FUNCTION on Mac.
478  if (asan_init_is_running) {
479    return REAL(memset)(block, c, size);
480  }
481  ENSURE_ASAN_INITED();
482  if (FLAG_replace_intrin) {
483    ASAN_WRITE_RANGE(block, size);
484  }
485  return REAL(memset)(block, c, size);
486}
487
488INTERCEPTOR(char*, strchr, const char *str, int c) {
489  ENSURE_ASAN_INITED();
490  char *result = REAL(strchr)(str, c);
491  if (FLAG_replace_str) {
492    size_t bytes_read = (result ? result - str : REAL(strlen)(str)) + 1;
493    ASAN_READ_RANGE(str, bytes_read);
494  }
495  return result;
496}
497
498#ifdef __linux__
499INTERCEPTOR(char*, index, const char *string, int c)
500  ALIAS(WRAPPER_NAME(strchr));
501#else
502DEFINE_REAL(char*, index, const char *string, int c);
503#endif
504
505#ifdef ANDROID
506DEFINE_REAL(int, sigaction, int signum, const struct sigaction *act,
507    struct sigaction *oldact);
508#endif
509
510INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
511  ENSURE_ASAN_INITED();
512  unsigned char c1, c2;
513  size_t i;
514  for (i = 0; ; i++) {
515    c1 = (unsigned char)s1[i];
516    c2 = (unsigned char)s2[i];
517    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
518  }
519  ASAN_READ_RANGE(s1, i + 1);
520  ASAN_READ_RANGE(s2, i + 1);
521  return CharCaseCmp(c1, c2);
522}
523
524INTERCEPTOR(char*, strcat, char *to, const char *from) {  // NOLINT
525  ENSURE_ASAN_INITED();
526  if (FLAG_replace_str) {
527    size_t from_length = REAL(strlen)(from);
528    ASAN_READ_RANGE(from, from_length + 1);
529    if (from_length > 0) {
530      size_t to_length = REAL(strlen)(to);
531      ASAN_READ_RANGE(to, to_length);
532      ASAN_WRITE_RANGE(to + to_length, from_length + 1);
533      CHECK_RANGES_OVERLAP("strcat", to, to_length + 1, from, from_length + 1);
534    }
535  }
536  return REAL(strcat)(to, from);  // NOLINT
537}
538
539INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
540  if (!asan_inited) {
541    return internal_strcmp(s1, s2);
542  }
543  unsigned char c1, c2;
544  size_t i;
545  for (i = 0; ; i++) {
546    c1 = (unsigned char)s1[i];
547    c2 = (unsigned char)s2[i];
548    if (c1 != c2 || c1 == '\0') break;
549  }
550  ASAN_READ_RANGE(s1, i + 1);
551  ASAN_READ_RANGE(s2, i + 1);
552  return CharCmp(c1, c2);
553}
554
555INTERCEPTOR(char*, strcpy, char *to, const char *from) {  // NOLINT
556  // strcpy is called from malloc_default_purgeable_zone()
557  // in __asan::ReplaceSystemAlloc() on Mac.
558  if (asan_init_is_running) {
559    return REAL(strcpy)(to, from);  // NOLINT
560  }
561  ENSURE_ASAN_INITED();
562  if (FLAG_replace_str) {
563    size_t from_size = REAL(strlen)(from) + 1;
564    CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size);
565    ASAN_READ_RANGE(from, from_size);
566    ASAN_WRITE_RANGE(to, from_size);
567  }
568  return REAL(strcpy)(to, from);  // NOLINT
569}
570
571INTERCEPTOR(char*, strdup, const char *s) {
572  ENSURE_ASAN_INITED();
573  if (FLAG_replace_str) {
574    size_t length = REAL(strlen)(s);
575    ASAN_READ_RANGE(s, length + 1);
576  }
577  return REAL(strdup)(s);
578}
579
580INTERCEPTOR(size_t, strlen, const char *s) {
581  // strlen is called from malloc_default_purgeable_zone()
582  // in __asan::ReplaceSystemAlloc() on Mac.
583  if (asan_init_is_running) {
584    return REAL(strlen)(s);
585  }
586  ENSURE_ASAN_INITED();
587  size_t length = REAL(strlen)(s);
588  if (FLAG_replace_str) {
589    ASAN_READ_RANGE(s, length + 1);
590  }
591  return length;
592}
593
594INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, size_t n) {
595  ENSURE_ASAN_INITED();
596  unsigned char c1 = 0, c2 = 0;
597  size_t i;
598  for (i = 0; i < n; i++) {
599    c1 = (unsigned char)s1[i];
600    c2 = (unsigned char)s2[i];
601    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
602  }
603  ASAN_READ_RANGE(s1, Min(i + 1, n));
604  ASAN_READ_RANGE(s2, Min(i + 1, n));
605  return CharCaseCmp(c1, c2);
606}
607
608INTERCEPTOR(int, strncmp, const char *s1, const char *s2, size_t size) {
609  // strncmp is called from malloc_default_purgeable_zone()
610  // in __asan::ReplaceSystemAlloc() on Mac.
611  if (asan_init_is_running) {
612    return REAL(strncmp)(s1, s2, size);
613  }
614  unsigned char c1 = 0, c2 = 0;
615  size_t i;
616  for (i = 0; i < size; i++) {
617    c1 = (unsigned char)s1[i];
618    c2 = (unsigned char)s2[i];
619    if (c1 != c2 || c1 == '\0') break;
620  }
621  ASAN_READ_RANGE(s1, Min(i + 1, size));
622  ASAN_READ_RANGE(s2, Min(i + 1, size));
623  return CharCmp(c1, c2);
624}
625
626INTERCEPTOR(char*, strncpy, char *to, const char *from, size_t size) {
627  ENSURE_ASAN_INITED();
628  if (FLAG_replace_str) {
629    size_t from_size = Min(size, internal_strnlen(from, size) + 1);
630    CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size);
631    ASAN_READ_RANGE(from, from_size);
632    ASAN_WRITE_RANGE(to, size);
633  }
634  return REAL(strncpy)(to, from, size);
635}
636
637#if ASAN_INTERCEPT_STRNLEN
638INTERCEPTOR(size_t, strnlen, const char *s, size_t maxlen) {
639  ENSURE_ASAN_INITED();
640  size_t length = REAL(strnlen)(s, maxlen);
641  if (FLAG_replace_str) {
642    ASAN_READ_RANGE(s, Min(length + 1, maxlen));
643  }
644  return length;
645}
646#endif  // ASAN_INTERCEPT_STRNLEN
647
648# if ASAN_INTERCEPT_STRTOLL
649// Returns pointer to first character of "nptr" after skipping
650// leading blanks and optional +/- sign.
651static char *SkipBlanksAndSign(const char *nptr) {
652  while (IsSpace(*nptr)) nptr++;
653  if (*nptr == '+' || *nptr == '-') nptr++;
654  return (char*)nptr;
655}
656
657INTERCEPTOR(long long, strtoll, const char *nptr,  // NOLINT
658            char **endptr, int base) {
659  ENSURE_ASAN_INITED();
660  if (!FLAG_replace_str) {
661    return REAL(strtoll)(nptr, endptr, base);
662  }
663  char *real_endptr;
664  long long result = REAL(strtoll)(nptr, &real_endptr, base);  // NOLINT
665  if (endptr != NULL) {
666    *endptr = real_endptr;
667  }
668  // If base has unsupported value, strtoll can exit with EINVAL
669  // without reading any characters. So do additional checks only
670  // if base is valid.
671  if (base == 0 || (2 <= base && base <= 36)) {
672    if (real_endptr == nptr) {
673      // No digits were found, find out the last symbol read by strtoll
674      // on our own.
675      real_endptr = SkipBlanksAndSign(nptr);
676    }
677    CHECK(real_endptr >= nptr);
678    ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
679  }
680  return result;
681}
682#endif  // ASAN_INTERCEPT_STRTOLL
683
684#if defined(_WIN32)
685INTERCEPTOR_WINAPI(DWORD, CreateThread,
686                   void* security, size_t stack_size,
687                   DWORD (__stdcall *start_routine)(void*), void* arg,
688                   DWORD flags, void* tid) {
689  GET_STACK_TRACE_HERE(kStackTraceMax);
690  int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
691  AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack);
692  asanThreadRegistry().RegisterThread(t);
693  return REAL(CreateThread)(security, stack_size,
694                            asan_thread_start, t, flags, tid);
695}
696
697namespace __asan {
698void InitializeWindowsInterceptors() {
699  CHECK(INTERCEPT_FUNCTION(CreateThread));
700}
701
702}  // namespace __asan
703#endif
704
705// ---------------------- InitializeAsanInterceptors ---------------- {{{1
706namespace __asan {
707void InitializeAsanInterceptors() {
708  static bool was_called_once;
709  CHECK(was_called_once == false);
710  was_called_once = true;
711  // Intercept mem* functions.
712  CHECK(INTERCEPT_FUNCTION(memcmp));
713  CHECK(INTERCEPT_FUNCTION(memmove));
714  CHECK(INTERCEPT_FUNCTION(memset));
715  if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) {
716    CHECK(INTERCEPT_FUNCTION(memcpy));
717  } else {
718    REAL(memcpy) = REAL(memmove);
719  }
720
721  // Intercept str* functions.
722  CHECK(INTERCEPT_FUNCTION(strcat));  // NOLINT
723  CHECK(INTERCEPT_FUNCTION(strchr));
724  CHECK(INTERCEPT_FUNCTION(strcmp));
725  CHECK(INTERCEPT_FUNCTION(strcpy));  // NOLINT
726  CHECK(INTERCEPT_FUNCTION(strlen));
727  CHECK(INTERCEPT_FUNCTION(strncmp));
728  CHECK(INTERCEPT_FUNCTION(strncpy));
729#if !defined(_WIN32)
730  CHECK(INTERCEPT_FUNCTION(strcasecmp));
731  CHECK(INTERCEPT_FUNCTION(strdup));
732  CHECK(INTERCEPT_FUNCTION(strncasecmp));
733# ifndef __APPLE__
734  CHECK(INTERCEPT_FUNCTION(index));
735# else
736  CHECK(OVERRIDE_FUNCTION(index, WRAP(strchr)));
737# endif
738#endif
739#if ASAN_INTERCEPT_STRNLEN
740  CHECK(INTERCEPT_FUNCTION(strnlen));
741#endif
742
743#if ASAN_INTERCEPT_STRTOLL
744  CHECK(INTERCEPT_FUNCTION(strtoll));
745#endif
746
747  // Intecept signal- and jump-related functions.
748  CHECK(INTERCEPT_FUNCTION(longjmp));
749#if !defined(ANDROID) && !defined(_WIN32)
750  CHECK(INTERCEPT_FUNCTION(sigaction));
751  CHECK(INTERCEPT_FUNCTION(signal));
752#endif
753
754#if !defined(_WIN32)
755  CHECK(INTERCEPT_FUNCTION(_longjmp));
756  INTERCEPT_FUNCTION(__cxa_throw);
757# if !defined(__APPLE__)
758  // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it
759  // there.
760  CHECK(INTERCEPT_FUNCTION(siglongjmp));
761# endif
762#endif
763
764  // Intercept threading-related functions
765#if !defined(_WIN32)
766  CHECK(INTERCEPT_FUNCTION(pthread_create));
767#endif
768
769  // Some Windows-specific interceptors.
770#if defined(_WIN32)
771  InitializeWindowsInterceptors();
772#endif
773
774  // Some Mac-specific interceptors.
775#if defined(__APPLE__)
776  InitializeMacInterceptors();
777#endif
778
779  if (FLAG_v > 0) {
780    Report("AddressSanitizer: libc interceptors initialized\n");
781  }
782}
783
784}  // namespace __asan
785