asan_interceptors.cc revision e236dbb5e558b174609d2d13e80685d488c129d8
17a653cb24d4dda283d34c984e81514ac1547796eGordon Henriksen//===-- asan_interceptors.cc ----------------------------------------------===// 28ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// 38ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// The LLVM Compiler Infrastructure 48ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// 58ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// This file is distributed under the University of Illinois Open Source 68ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// License. See LICENSE.TXT for details. 78ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// 88ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen//===----------------------------------------------------------------------===// 98ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// 108ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// This file is a part of AddressSanitizer, an address sanity checker. 118ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// 128ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// Intercept various libc functions. 138ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen//===----------------------------------------------------------------------===// 14344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen#include "asan_interceptors.h" 158ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen 168ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#include "asan_allocator.h" 178ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#include "asan_intercepted_functions.h" 188ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#include "asan_internal.h" 198ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#include "asan_mapping.h" 20344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen#include "asan_poisoning.h" 218ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#include "asan_report.h" 228ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#include "asan_stack.h" 238ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#include "asan_stats.h" 24404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen#include "interception/interception.h" 2580a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksen#include "sanitizer_common/sanitizer_libc.h" 2680a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksen 278ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksennamespace __asan { 288ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen 298ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// Return true if we can quickly decide that the region is unpoisoned. 308ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksenstatic inline bool QuickCheckForUnpoisonedRegion(uptr beg, uptr size) { 318ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (size == 0) return true; 328ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (size <= 32) 338ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen return !AddressIsPoisoned(beg) && 348ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen !AddressIsPoisoned(beg + size - 1) && 358ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen !AddressIsPoisoned(beg + size / 2); 368ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen return false; 378ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen} 388ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen 39a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE, 40a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen// and ASAN_WRITE_RANGE as macro instead of function so 41a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen// that no extra frames are created, and stack trace contains 42a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen// relevant information only. 43a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen// We check all shadow bytes. 44a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \ 45a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen uptr __offset = (uptr)(offset); \ 46a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen uptr __size = (uptr)(size); \ 47a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen uptr __bad = 0; \ 48a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen if (!QuickCheckForUnpoisonedRegion(__offset, __size) && \ 49a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen (__bad = __asan_region_is_poisoned(__offset, __size))) { \ 50a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen GET_CURRENT_PC_BP_SP; \ 51a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen __asan_report_error(pc, bp, sp, __bad, isWrite, __size); \ 52a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen } \ 53a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen } while (0) 54a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen 55a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen#define ASAN_READ_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size, false) 56a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen#define ASAN_WRITE_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size, true) 57a353ffa7e556bfd2864474911174da691117f691Gordon Henriksen 588ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// Behavior of functions like "memcpy" or "strcpy" is undefined 598ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// if memory intervals overlap. We report error in this case. 608ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// Macro is used to avoid creation of new frames. 618ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksenstatic inline bool RangesOverlap(const char *offset1, uptr length1, 628ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen const char *offset2, uptr length2) { 638ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1)); 6446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 65404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \ 668ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen const char *offset1 = (const char*)_offset1; \ 678ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen const char *offset2 = (const char*)_offset2; \ 688ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (RangesOverlap(offset1, length1, offset2, length2)) { \ 698ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen GET_STACK_TRACE_FATAL_HERE; \ 7046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \ 71404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen offset2, length2, &stack); \ 728ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen } \ 738ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen} while (0) 748ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen 758ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#define ENSURE_ASAN_INITED() do { \ 7646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen CHECK(!asan_init_is_running); \ 778ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (!asan_inited) { \ 788ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen __asan_init(); \ 798ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen } \ 808ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen} while (0) 81957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen 8246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksenstatic inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) { 838ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#if ASAN_INTERCEPT_STRNLEN 848ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (REAL(strnlen) != 0) { 858ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen return REAL(strnlen)(s, maxlen); 868ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen } 8746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 88404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen return internal_strnlen(s, maxlen); 898ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen} 908ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen 918ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksenvoid SetThreadName(const char *name) { 928ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen AsanThread *t = GetCurrentThread(); 9346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (t) 94404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen asanThreadRegistry().SetThreadName(t->tid(), name); 958ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen} 968ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen 978ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksenint OnExit() { 988ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen // FIXME: ask frontend whether we need to return failure. 99957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen return 0; 10046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 101404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen 1028ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen} // namespace __asan 1038ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen 1048ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// ---------------------- Wrappers ---------------- {{{1 1058ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksenusing namespace __asan; // NOLINT 1068ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen 1078ef426baa36639458f6777309db25c1768dc9c8aGordon HenriksenDECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr) 108957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon HenriksenDECLARE_REAL_AND_INTERCEPTOR(void, free, void *) 109957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen 11046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#define COMMON_INTERCEPTOR_UNPOISON_PARAM(ctx, count) \ 1118ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen do { \ 1128ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen } while (false) 1138ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ 1148ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ASAN_WRITE_RANGE(ptr, size) 1158ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) ASAN_READ_RANGE(ptr, size) 116957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ 11746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen do { \ 1188ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (asan_init_is_running) return REAL(func)(__VA_ARGS__); \ 1198ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ctx = 0; \ 120404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen (void) ctx; \ 1218ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ENSURE_ASAN_INITED(); \ 12257cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen } while (false) 12357cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \ 12457cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen do { \ 12557cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen } while (false) 12657cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \ 12757cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen do { \ 12857cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen } while (false) 129404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \ 13057cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen do { \ 13157cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen } while (false) 13257cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name) 133ef989a275c1191f583178c6934f3594e7a9fd3a6Christopher Lamb#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name) 13457cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit() 13557cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen#include "sanitizer_common/sanitizer_common_interceptors.inc" 13657cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen 13757cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(p, s) 13857cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(p, s) 13957cebeec7ba08b55f29f5bf98ad0a3a17e9d0c71Gordon Henriksen#define COMMON_SYSCALL_POST_READ_RANGE(p, s) \ 1408ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen do { \ 1418ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen } while (false) 1428ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \ 1438ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen do { \ 144957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen } while (false) 14546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#include "sanitizer_common/sanitizer_common_syscalls.inc" 1468ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen 1478ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksenstatic thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { 1488ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen AsanThread *t = (AsanThread*)arg; 1498ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen SetCurrentThread(t); 1508ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen return t->ThreadStart(GetTid()); 1518ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen} 152957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen 15346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if ASAN_INTERCEPT_PTHREAD_CREATE 1548ef426baa36639458f6777309db25c1768dc9c8aGordon HenriksenINTERCEPTOR(int, pthread_create, void *thread, 155957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen void *attr, void *(*start_routine)(void*), void *arg) { 15646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen EnsureMainThreadIDIsCorrect(); 15746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // Strict init-order checking in thread-hostile. 15846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (flags()->strict_init_order) 15946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen StopInitOrderChecking(); 160957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen GET_STACK_TRACE_THREAD; 16146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen int detached = 0; 1621cf08fddc7413076dedad58dbb8d8d67e69a490fGordon Henriksen if (attr != 0) 1631cf08fddc7413076dedad58dbb8d8d67e69a490fGordon Henriksen pthread_attr_getdetachstate(attr, &detached); 1641cf08fddc7413076dedad58dbb8d8d67e69a490fGordon Henriksen 1651cf08fddc7413076dedad58dbb8d8d67e69a490fGordon Henriksen u32 current_tid = GetCurrentTidOrInvalid(); 1661cf08fddc7413076dedad58dbb8d8d67e69a490fGordon Henriksen AsanThread *t = AsanThread::Create(start_routine, arg); 1671cf08fddc7413076dedad58dbb8d8d67e69a490fGordon Henriksen CreateThreadContextArgs args = { t, &stack }; 1681cf08fddc7413076dedad58dbb8d8d67e69a490fGordon Henriksen asanThreadRegistry().CreateThread(*(uptr*)t, detached, current_tid, &args); 1691cf08fddc7413076dedad58dbb8d8d67e69a490fGordon Henriksen return REAL(pthread_create)(thread, attr, asan_thread_start, t); 1701cf08fddc7413076dedad58dbb8d8d67e69a490fGordon Henriksen} 1711cf08fddc7413076dedad58dbb8d8d67e69a490fGordon Henriksen#endif // ASAN_INTERCEPT_PTHREAD_CREATE 1721cf08fddc7413076dedad58dbb8d8d67e69a490fGordon Henriksen 1738ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 1748ef426baa36639458f6777309db25c1768dc9c8aGordon HenriksenINTERCEPTOR(void*, signal, int signum, void *handler) { 175344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen if (!AsanInterceptsSignal(signum) || flags()->allow_user_segv_handler) { 176344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen return REAL(signal)(signum, handler); 177344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen } 178344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen return 0; 179344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen} 180344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen 181e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon HenriksenINTERCEPTOR(int, sigaction, int signum, const struct sigaction *act, 182344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen struct sigaction *oldact) { 183344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen if (!AsanInterceptsSignal(signum) || flags()->allow_user_segv_handler) { 184344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen return REAL(sigaction)(signum, act, oldact); 185344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen } 186344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen return 0; 187344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen} 188344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen#elif SANITIZER_POSIX 189e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen// We need to have defined REAL(sigaction) on posix systems. 190344be5fbecec9908bab611eafeae0549ba3be6d7Gordon HenriksenDEFINE_REAL(int, sigaction, int signum, const struct sigaction *act, 191344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen struct sigaction *oldact) 192344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen#endif // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 193344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen 194344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen#if ASAN_INTERCEPT_SWAPCONTEXT 195344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksenstatic void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) { 196e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen // Align to page size. 197344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen uptr PageSize = GetPageSizeCached(); 198344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen uptr bottom = stack & ~(PageSize - 1); 199344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen ssize += stack - bottom; 200344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen ssize = RoundUpTo(ssize, PageSize); 201344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen static const uptr kMaxSaneContextStackSize = 1 << 22; // 4 Mb 202344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen if (ssize && ssize <= kMaxSaneContextStackSize) { 203e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen PoisonShadow(bottom, ssize, 0); 204344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen } 205957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen} 206344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen 207344be5fbecec9908bab611eafeae0549ba3be6d7Gordon HenriksenINTERCEPTOR(int, swapcontext, struct ucontext_t *oucp, 208344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen struct ucontext_t *ucp) { 209e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen static bool reported_warning = false; 210e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen if (!reported_warning) { 211344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen Report("WARNING: ASan doesn't fully support makecontext/swapcontext " 212957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen "functions and may produce false positives in some cases!\n"); 213344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen reported_warning = true; 214344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen } 215344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen // Clear shadow memory for new context (it may share stack 216344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen // with current context). 217e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen uptr stack, ssize; 218344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen ReadContextStack(ucp, &stack, &ssize); 219344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen ClearShadowMemoryForContextStack(stack, ssize); 220344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen int res = REAL(swapcontext)(oucp, ucp); 221e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen // swapcontext technically does not return, but program may swap context to 222e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen // "oucp" later, that would look as if swapcontext() returned 0. 223e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen // We need to clear shadow for ucp once again, as it may be in arbitrary 224e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen // state. 225344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen ClearShadowMemoryForContextStack(stack, ssize); 226344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen return res; 227344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen} 228344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen#endif // ASAN_INTERCEPT_SWAPCONTEXT 229e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen 230344be5fbecec9908bab611eafeae0549ba3be6d7Gordon HenriksenINTERCEPTOR(void, longjmp, void *env, int val) { 231957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen __asan_handle_no_return(); 232344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen REAL(longjmp)(env, val); 233344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen} 234344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen 235344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen#if ASAN_INTERCEPT__LONGJMP 236e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon HenriksenINTERCEPTOR(void, _longjmp, void *env, int val) { 237e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen __asan_handle_no_return(); 238344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen REAL(_longjmp)(env, val); 239957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen} 240344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen#endif 241344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen 242344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen#if ASAN_INTERCEPT_SIGLONGJMP 243344be5fbecec9908bab611eafeae0549ba3be6d7Gordon HenriksenINTERCEPTOR(void, siglongjmp, void *env, int val) { 244e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen __asan_handle_no_return(); 245344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen REAL(siglongjmp)(env, val); 246957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen} 247344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen#endif 248344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen 249344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen#if ASAN_INTERCEPT___CXA_THROW 250344be5fbecec9908bab611eafeae0549ba3be6d7Gordon HenriksenINTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { 251344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen CHECK(REAL(__cxa_throw)); 252957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen __asan_handle_no_return(); 253957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen REAL(__cxa_throw)(a, b, c); 254344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen} 255344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen#endif 256344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen 257344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen// intercept mlock and friends. 258344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen// Since asan maps 16T of RAM, mlock is completely unfriendly to asan. 259e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen// All functions return 0 (success). 260344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksenstatic void MlockIsUnsupported() { 261344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen static bool printed = false; 262344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen if (printed) return; 263344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen printed = true; 264344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen if (common_flags()->verbosity > 0) { 265e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen Printf("INFO: AddressSanitizer ignores " 266344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen "mlock/mlockall/munlock/munlockall\n"); 267344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen } 2684647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen} 2694647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen 2704647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon HenriksenINTERCEPTOR(int, mlock, const void *addr, uptr len) { 2714647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen MlockIsUnsupported(); 2724647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen return 0; 2734647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen} 2744647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen 2754647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon HenriksenINTERCEPTOR(int, munlock, const void *addr, uptr len) { 2764647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen MlockIsUnsupported(); 2774647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen return 0; 2784647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen} 2794647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen 2804647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon HenriksenINTERCEPTOR(int, mlockall, int flags) { 2814647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen MlockIsUnsupported(); 2824647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen return 0; 2834647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen} 2844647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen 2854647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon HenriksenINTERCEPTOR(int, munlockall, void) { 2864647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen MlockIsUnsupported(); 2874647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen return 0; 288957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen} 289e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen 2904647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksenstatic inline int CharCmp(unsigned char c1, unsigned char c2) { 291e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 2924647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen} 2934647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen 2944647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon HenriksenINTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { 2954647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen if (!asan_inited) return internal_memcmp(a1, a2, size); 2964647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen ENSURE_ASAN_INITED(); 2974647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen if (flags()->replace_intrin) { 2984647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen if (flags()->strict_memcmp) { 2994647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen // Check the entire regions even if the first bytes of the buffers are 3004647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen // different. 3014647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen ASAN_READ_RANGE(a1, size); 3024647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen ASAN_READ_RANGE(a2, size); 3034647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen // Fallthrough to REAL(memcmp) below. 3044647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen } else { 3054647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen unsigned char c1 = 0, c2 = 0; 3064647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen const unsigned char *s1 = (const unsigned char*)a1; 3074647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen const unsigned char *s2 = (const unsigned char*)a2; 308404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen uptr i; 309404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen for (i = 0; i < size; i++) { 3104647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen c1 = s1[i]; 3114647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen c2 = s2[i]; 3124647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen if (c1 != c2) break; 3134647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen } 3144647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen ASAN_READ_RANGE(s1, Min(i + 1, size)); 3154647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen ASAN_READ_RANGE(s2, Min(i + 1, size)); 3164647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen return CharCmp(c1, c2); 3174647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen } 3184647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen } 3194647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen return REAL(memcmp(a1, a2, size)); 3204647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen} 3214647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen 3224647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen#define MEMMOVE_BODY { \ 3234647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen if (!asan_inited) return internal_memmove(to, from, size); \ 3244647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen if (asan_init_is_running) { \ 325957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen return REAL(memmove)(to, from, size); \ 3264647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen } \ 3274647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen ENSURE_ASAN_INITED(); \ 3284647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen if (flags()->replace_intrin) { \ 3294647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen ASAN_READ_RANGE(from, size); \ 3304647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen ASAN_WRITE_RANGE(to, size); \ 3314647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen } \ 3324647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen return internal_memmove(to, from, size); \ 3334647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen} 3344647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen 3354647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon HenriksenINTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) MEMMOVE_BODY 3364647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen 337957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon HenriksenINTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) { 338e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen#if !SANITIZER_MAC 3394647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen if (!asan_inited) return internal_memcpy(to, from, size); 3404647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen // memcpy is called during __asan_init() from the internals 3414647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen // of printf(...). 3424647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen if (asan_init_is_running) { 3434647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen return REAL(memcpy)(to, from, size); 3444647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen } 3454647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen ENSURE_ASAN_INITED(); 3464647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen if (flags()->replace_intrin) { 3474647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen if (to != from) { 3484647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen // We do not treat memcpy with to==from as a bug. 3494647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen // See http://llvm.org/bugs/show_bug.cgi?id=11763. 3504647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); 3514647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen } 352957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen ASAN_READ_RANGE(from, size); 3534647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen ASAN_WRITE_RANGE(to, size); 3544647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen } 355404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8, so 356e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen // calling REAL(memcpy) here leads to infinite recursion. 357e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116. 358e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen return internal_memcpy(to, from, size); 359e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen#else 3604647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen // At least on 10.7 and 10.8 both memcpy() and memmove() are being replaced 361e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen // with WRAP(memcpy). As a result, false positives are reported for memmove() 3624647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen // calls. If we just disable error reporting with 3634647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen // ASAN_OPTIONS=replace_intrin=0, memmove() is still replaced with 364e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen // internal_memcpy(), which may lead to crashes, see 3654647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen // http://llvm.org/bugs/show_bug.cgi?id=16362. 3664647569fe7706e76135a08ca0e5f90a447ccc5b4Gordon Henriksen MEMMOVE_BODY 367e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen#endif // !SANITIZER_MAC 368e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen} 369957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen 370344be5fbecec9908bab611eafeae0549ba3be6d7Gordon HenriksenINTERCEPTOR(void*, memset, void *block, int c, uptr size) { 371344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen if (!asan_inited) return internal_memset(block, c, size); 3728ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen // memset is called inside Printf. 3738ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (asan_init_is_running) { 3748ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen return REAL(memset)(block, c, size); 3758ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen } 376e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen ENSURE_ASAN_INITED(); 3778ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (flags()->replace_intrin) { 3788ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ASAN_WRITE_RANGE(block, size); 3798ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen } 3808ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen return REAL(memset)(block, c, size); 3818ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen} 3828ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen 3838ef426baa36639458f6777309db25c1768dc9c8aGordon HenriksenINTERCEPTOR(char*, strchr, const char *str, int c) { 3848ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (!asan_inited) return internal_strchr(str, c); 3858ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen // strchr is called inside create_purgeable_zone() when MallocGuardEdges=1 is 3868ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen // used. 3878ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (asan_init_is_running) { 3888ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen return REAL(strchr)(str, c); 3898ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen } 390404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen ENSURE_ASAN_INITED(); 391404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen char *result = REAL(strchr)(str, c); 3928ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (flags()->replace_str) { 3938ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen uptr bytes_read = (result ? result - str : REAL(strlen)(str)) + 1; 3948ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ASAN_READ_RANGE(str, bytes_read); 3958ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen } 3968ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen return result; 3978ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen} 3988ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen 3998ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#if ASAN_INTERCEPT_INDEX 4008ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen# if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 4018ef426baa36639458f6777309db25c1768dc9c8aGordon HenriksenINTERCEPTOR(char*, index, const char *string, int c) 4028ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ALIAS(WRAPPER_NAME(strchr)); 4038ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen# else 404404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen# if SANITIZER_MAC 405404a1942e43ca967700cc2608eb97b863add2677Gordon HenriksenDECLARE_REAL(char*, index, const char *string, int c) 4068ef426baa36639458f6777309db25c1768dc9c8aGordon HenriksenOVERRIDE_FUNCTION(index, strchr); 4078ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen# else 4088ef426baa36639458f6777309db25c1768dc9c8aGordon HenriksenDEFINE_REAL(char*, index, const char *string, int c) 4098ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen# endif 4108ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen# endif 4118ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#endif // ASAN_INTERCEPT_INDEX 4128ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen 4138ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// For both strcat() and strncat() we need to check the validity of |to| 4148ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen// argument irrespective of the |from| length. 4158ef426baa36639458f6777309db25c1768dc9c8aGordon HenriksenINTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT 4168ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ENSURE_ASAN_INITED(); 4178ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (flags()->replace_str) { 4188ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen uptr from_length = REAL(strlen)(from); 419e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen ASAN_READ_RANGE(from, from_length + 1); 4208ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen uptr to_length = REAL(strlen)(to); 4218ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ASAN_READ_RANGE(to, to_length); 4228ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ASAN_WRITE_RANGE(to + to_length, from_length + 1); 4238ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen // If the copying actually happens, the |from| string should not overlap 4246d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen // with the resulting string starting at |to|, which has a length of 4258ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen // to_length + from_length + 1. 4268ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (from_length > 0) { 4276d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1, 4286d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen from, from_length + 1); 4296d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen } 4306d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen } 4316d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen return REAL(strcat)(to, from); // NOLINT 4328ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen} 4338ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen 4348ef426baa36639458f6777309db25c1768dc9c8aGordon HenriksenINTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) { 4358ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ENSURE_ASAN_INITED(); 4368ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (flags()->replace_str) { 4378ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen uptr from_length = MaybeRealStrnlen(from, size); 4388ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen uptr copy_length = Min(size, from_length + 1); 4398ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ASAN_READ_RANGE(from, copy_length); 4408ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen uptr to_length = REAL(strlen)(to); 4418ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ASAN_READ_RANGE(to, to_length); 4428ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ASAN_WRITE_RANGE(to + to_length, from_length + 1); 4438ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen if (from_length > 0) { 4448ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1, 4458ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen from, copy_length); 4468ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen } 4478ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen } 4488ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen return REAL(strncat)(to, from, size); 4498ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen} 4508ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen 4518ef426baa36639458f6777309db25c1768dc9c8aGordon HenriksenINTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT 4528ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#if SANITIZER_MAC 453344be5fbecec9908bab611eafeae0549ba3be6d7Gordon Henriksen if (!asan_inited) return REAL(strcpy)(to, from); // NOLINT 4548ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen#endif 455c84c16be9b29b4f805b92bfc2d93e2dfaa952f8fGordon Henriksen // strcpy is called from malloc_default_purgeable_zone() 456c84c16be9b29b4f805b92bfc2d93e2dfaa952f8fGordon Henriksen // in __asan::ReplaceSystemAlloc() on Mac. 457c84c16be9b29b4f805b92bfc2d93e2dfaa952f8fGordon Henriksen if (asan_init_is_running) { 458c84c16be9b29b4f805b92bfc2d93e2dfaa952f8fGordon Henriksen return REAL(strcpy)(to, from); // NOLINT 459c84c16be9b29b4f805b92bfc2d93e2dfaa952f8fGordon Henriksen } 460c84c16be9b29b4f805b92bfc2d93e2dfaa952f8fGordon Henriksen ENSURE_ASAN_INITED(); 461c84c16be9b29b4f805b92bfc2d93e2dfaa952f8fGordon Henriksen if (flags()->replace_str) { 462c84c16be9b29b4f805b92bfc2d93e2dfaa952f8fGordon Henriksen uptr from_size = REAL(strlen)(from) + 1; 463c84c16be9b29b4f805b92bfc2d93e2dfaa952f8fGordon Henriksen CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size); 4648ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ASAN_READ_RANGE(from, from_size); 4658ef426baa36639458f6777309db25c1768dc9c8aGordon Henriksen ASAN_WRITE_RANGE(to, from_size); 46646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 46746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return REAL(strcpy)(to, from); // NOLINT 46846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 469957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen 4706d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen#if ASAN_INTERCEPT_STRDUP 47146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon HenriksenINTERCEPTOR(char*, strdup, const char *s) { 47246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (!asan_inited) return internal_strdup(s); 47346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ENSURE_ASAN_INITED(); 47446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen uptr length = REAL(strlen)(s); 4756d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen if (flags()->replace_str) { 47646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_READ_RANGE(s, length + 1); 4776d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen } 47846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen GET_STACK_TRACE_MALLOC; 47946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen void *new_mem = asan_malloc(length + 1, &stack); 4806d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen REAL(memcpy)(new_mem, s, length + 1); 4816d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen return reinterpret_cast<char*>(new_mem); 4826d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen} 4836d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen#endif 4846d6203dff3560a2cc3ac8ec620ac3b105b0c7cc7Gordon Henriksen 48546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon HenriksenINTERCEPTOR(uptr, strlen, const char *s) { 48646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (!asan_inited) return internal_strlen(s); 48746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // strlen is called from malloc_default_purgeable_zone() 48846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // in __asan::ReplaceSystemAlloc() on Mac. 48946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (asan_init_is_running) { 49046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return REAL(strlen)(s); 49146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 49246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ENSURE_ASAN_INITED(); 49346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen uptr length = REAL(strlen)(s); 49446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (flags()->replace_str) { 49546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_READ_RANGE(s, length + 1); 49646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 49746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return length; 4982618a6c1122d5d2007787fb56156be44b21ab32aGordon Henriksen} 49946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 50046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon HenriksenINTERCEPTOR(uptr, wcslen, const wchar_t *s) { 50146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen uptr length = REAL(wcslen)(s); 50246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (!asan_init_is_running) { 50346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ENSURE_ASAN_INITED(); 50446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_READ_RANGE(s, (length + 1) * sizeof(wchar_t)); 50546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 50646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return length; 50746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 50846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 50946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon HenriksenINTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) { 51046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ENSURE_ASAN_INITED(); 51146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (flags()->replace_str) { 5122618a6c1122d5d2007787fb56156be44b21ab32aGordon Henriksen uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1); 51346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size); 51446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_READ_RANGE(from, from_size); 51546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_WRITE_RANGE(to, size); 51646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 51746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return REAL(strncpy)(to, from, size); 5181475142b93a618da72ec471e5ad7c1510c2feb37Gordon Henriksen} 5191475142b93a618da72ec471e5ad7c1510c2feb37Gordon Henriksen 5201475142b93a618da72ec471e5ad7c1510c2feb37Gordon Henriksen#if ASAN_INTERCEPT_STRNLEN 52180a75bfae980df96f969f1c05b0c4a80ce975240Gordon HenriksenINTERCEPTOR(uptr, strnlen, const char *s, uptr maxlen) { 52280a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksen ENSURE_ASAN_INITED(); 52380a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksen uptr length = REAL(strnlen)(s, maxlen); 52480a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksen if (flags()->replace_str) { 52580a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksen ASAN_READ_RANGE(s, Min(length + 1, maxlen)); 52680a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksen } 52780a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksen return length; 52880a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksen} 52980a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksen#endif // ASAN_INTERCEPT_STRNLEN 53080a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksen 53180a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksenstatic inline bool IsValidStrtolBase(int base) { 53280a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksen return (base == 0) || (2 <= base && base <= 36); 53380a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksen} 53480a75bfae980df96f969f1c05b0c4a80ce975240Gordon Henriksen 53546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksenstatic inline void FixRealStrtolEndptr(const char *nptr, char **endptr) { 53646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen CHECK(endptr); 53746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (nptr == *endptr) { 53846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // No digits were found at strtol call, we need to find out the last 53946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // symbol accessed by strtoll on our own. 540957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen // We get this symbol by skipping leading blanks and optional +/- sign. 54146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen while (IsSpace(*nptr)) nptr++; 54246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (*nptr == '+' || *nptr == '-') nptr++; 54346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen *endptr = (char*)nptr; 54446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 54546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen CHECK(*endptr >= nptr); 54646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 54746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 5482618a6c1122d5d2007787fb56156be44b21ab32aGordon HenriksenINTERCEPTOR(long, strtol, const char *nptr, // NOLINT 54946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen char **endptr, int base) { 55046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ENSURE_ASAN_INITED(); 55146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (!flags()->replace_str) { 55246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return REAL(strtol)(nptr, endptr, base); 55346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 55446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen char *real_endptr; 55546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT 55646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (endptr != 0) { 55746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen *endptr = real_endptr; 55846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 5592618a6c1122d5d2007787fb56156be44b21ab32aGordon Henriksen if (IsValidStrtolBase(base)) { 5602618a6c1122d5d2007787fb56156be44b21ab32aGordon Henriksen FixRealStrtolEndptr(nptr, &real_endptr); 56146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 5622618a6c1122d5d2007787fb56156be44b21ab32aGordon Henriksen } 5632618a6c1122d5d2007787fb56156be44b21ab32aGordon Henriksen return result; 56446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 56546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 56646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon HenriksenINTERCEPTOR(int, atoi, const char *nptr) { 56746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if SANITIZER_MAC 56846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (!asan_inited) return REAL(atoi)(nptr); 56946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 5702618a6c1122d5d2007787fb56156be44b21ab32aGordon Henriksen ENSURE_ASAN_INITED(); 57146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (!flags()->replace_str) { 57246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return REAL(atoi)(nptr); 57346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 57446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen char *real_endptr; 57546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // "man atoi" tells that behavior of atoi(nptr) is the same as 57646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the 57746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // parsed integer can't be stored in *long* type (even if it's 5782618a6c1122d5d2007787fb56156be44b21ab32aGordon Henriksen // different from int). So, we just imitate this behavior. 57946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen int result = REAL(strtol)(nptr, &real_endptr, 10); 58046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen FixRealStrtolEndptr(nptr, &real_endptr); 581e3b989d4a4ba47f77d5d38c35ff17e9673d9f87bGordon Henriksen ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 58246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return result; 58346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 58446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 58546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon HenriksenINTERCEPTOR(long, atol, const char *nptr) { // NOLINT 58646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if SANITIZER_MAC 58746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (!asan_inited) return REAL(atol)(nptr); 58846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 58946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ENSURE_ASAN_INITED(); 59046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (!flags()->replace_str) { 59146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return REAL(atol)(nptr); 59246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 593957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen char *real_endptr; 59446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT 59546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen FixRealStrtolEndptr(nptr, &real_endptr); 59646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 59746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return result; 59846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 59946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 600957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 60146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon HenriksenINTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT 60246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen char **endptr, int base) { 60346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ENSURE_ASAN_INITED(); 60446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (!flags()->replace_str) { 60546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return REAL(strtoll)(nptr, endptr, base); 60646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 60746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen char *real_endptr; 60846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT 60946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (endptr != 0) { 61046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen *endptr = real_endptr; 61146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 61246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // If base has unsupported value, strtoll can exit with EINVAL 61346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // without reading any characters. So do additional checks only 61446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // if base is valid. 61546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (IsValidStrtolBase(base)) { 61646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen FixRealStrtolEndptr(nptr, &real_endptr); 61746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 61846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 61946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return result; 62046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 62146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 62246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon HenriksenINTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT 62346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ENSURE_ASAN_INITED(); 62446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (!flags()->replace_str) { 62546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return REAL(atoll)(nptr); 62646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 62746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen char *real_endptr; 62846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT 62946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen FixRealStrtolEndptr(nptr, &real_endptr); 63046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 63146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return result; 63246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 63346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL 63446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 63546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksenstatic void AtCxaAtexit(void *unused) { 63646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen (void)unused; 63746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen StopInitOrderChecking(); 63846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 63946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 64046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if ASAN_INTERCEPT___CXA_ATEXIT 64146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon HenriksenINTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, 64246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen void *dso_handle) { 64346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ENSURE_ASAN_INITED(); 64446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen int res = REAL(__cxa_atexit)(func, arg, dso_handle); 64546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen REAL(__cxa_atexit)(AtCxaAtexit, 0, 0); 64646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return res; 64746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 64846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif // ASAN_INTERCEPT___CXA_ATEXIT 64946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 65046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if !SANITIZER_MAC 65146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#define ASAN_INTERCEPT_FUNC(name) do { \ 65246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (!INTERCEPT_FUNCTION(name) && common_flags()->verbosity > 0) \ 65346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen Report("AddressSanitizer: failed to intercept '" #name "'\n"); \ 65446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } while (0) 65546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#else 65646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen// OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION. 65746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#define ASAN_INTERCEPT_FUNC(name) 65846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif // SANITIZER_MAC 65946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 66046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if SANITIZER_WINDOWS 66146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon HenriksenINTERCEPTOR_WINAPI(DWORD, CreateThread, 66246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen void* security, uptr stack_size, 66346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen DWORD (__stdcall *start_routine)(void*), void* arg, 66446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen DWORD thr_flags, void* tid) { 66546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // Strict init-order checking in thread-hostile. 66646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (flags()->strict_init_order) 66746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen StopInitOrderChecking(); 66846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen GET_STACK_TRACE_THREAD; 66946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen u32 current_tid = GetCurrentTidOrInvalid(); 67046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen AsanThread *t = AsanThread::Create(start_routine, arg); 67146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen CreateThreadContextArgs args = { t, &stack }; 67246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen bool detached = false; // FIXME: how can we determine it on Windows? 67346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen asanThreadRegistry().CreateThread(*(uptr*)t, detached, current_tid, &args); 67446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen return REAL(CreateThread)(security, stack_size, 67546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen asan_thread_start, t, thr_flags, tid); 67646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 67746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 67846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksennamespace __asan { 67946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksenvoid InitializeWindowsInterceptors() { 68046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(CreateThread); 68146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 68246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 68346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} // namespace __asan 68446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 68546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 68646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen// ---------------------- InitializeAsanInterceptors ---------------- {{{1 68746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksennamespace __asan { 68846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksenvoid InitializeAsanInterceptors() { 68946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen static bool was_called_once; 69046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen CHECK(was_called_once == false); 69146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen was_called_once = true; 69246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen SANITIZER_COMMON_INTERCEPTORS_INIT; 69346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 69446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // Intercept mem* functions. 69546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(memcmp); 69646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(memmove); 69746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(memset); 69846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { 69946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(memcpy); 7002618a6c1122d5d2007787fb56156be44b21ab32aGordon Henriksen } 7012618a6c1122d5d2007787fb56156be44b21ab32aGordon Henriksen 70246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // Intercept str* functions. 70346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(strcat); // NOLINT 70446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(strchr); 70546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(strcpy); // NOLINT 70646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(strlen); 70746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(wcslen); 70846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(strncat); 70946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(strncpy); 71046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if ASAN_INTERCEPT_STRDUP 71146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(strdup); 71246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 71346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if ASAN_INTERCEPT_STRNLEN 71446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(strnlen); 71546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 71646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 71746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(index); 71846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 71946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 72046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(atoi); 72146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(atol); 72246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(strtol); 72346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 7242618a6c1122d5d2007787fb56156be44b21ab32aGordon Henriksen ASAN_INTERCEPT_FUNC(atoll); 7252618a6c1122d5d2007787fb56156be44b21ab32aGordon Henriksen ASAN_INTERCEPT_FUNC(strtoll); 72646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 72746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 72846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if ASAN_INTERCEPT_MLOCKX 729957f9fe1cce0957bcde4a1093da83e17aaec6764Gordon Henriksen // Intercept mlock/munlock. 73046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(mlock); 73146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(munlock); 73246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(mlockall); 73346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(munlockall); 73446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 73546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 73646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // Intecept signal- and jump-related functions. 73746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(longjmp); 73846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 73946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(sigaction); 74046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(signal); 74146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 74246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if ASAN_INTERCEPT_SWAPCONTEXT 74346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(swapcontext); 74446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 74546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if ASAN_INTERCEPT__LONGJMP 74646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(_longjmp); 74746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 74846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if ASAN_INTERCEPT_SIGLONGJMP 74946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(siglongjmp); 75046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 75146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 75246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // Intercept exception handling functions. 75346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if ASAN_INTERCEPT___CXA_THROW 75446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen INTERCEPT_FUNCTION(__cxa_throw); 75546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 75646abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 75746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // Intercept threading-related functions 75846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if ASAN_INTERCEPT_PTHREAD_CREATE 75946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen ASAN_INTERCEPT_FUNC(pthread_create); 76046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 76146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 76246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen // Intercept atexit function. 76346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if ASAN_INTERCEPT___CXA_ATEXIT 764404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen ASAN_INTERCEPT_FUNC(__cxa_atexit); 765404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen#endif 766404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen 767404a1942e43ca967700cc2608eb97b863add2677Gordon Henriksen // Some Windows-specific interceptors. 76846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#if SANITIZER_WINDOWS 76946abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen InitializeWindowsInterceptors(); 77046abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen#endif 77146abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen 77246abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen if (common_flags()->verbosity > 0) { 77346abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen Report("AddressSanitizer: libc interceptors initialized\n"); 77446abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen } 77546abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} 7762618a6c1122d5d2007787fb56156be44b21ab32aGordon Henriksen 77746abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen} // namespace __asan 77846abf91f7378fb7bb118d66fe6d69b5d3af1e9d5Gordon Henriksen