asan_interceptors.cc revision 8cde99fb9df913aaf7c1715cd134110dd5a15834
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- asan_interceptors.cc ----------------------------------------------===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is a part of AddressSanitizer, an address sanity checker. 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Intercept various libc functions. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 14558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "asan_interceptors.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "asan_allocator.h" 1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "asan_intercepted_functions.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "asan_internal.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "asan_mapping.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "asan_poisoning.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "asan_report.h" 22558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "asan_stack.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "asan_stats.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "interception/interception.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sanitizer_common/sanitizer_libc.h" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 27558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochnamespace __asan { 28558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 29558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Return true if we can quickly decide that the region is unpoisoned. 30a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochstatic inline bool QuickCheckForUnpoisonedRegion(uptr beg, uptr size) { 31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (size == 0) return true; 32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (size <= 32) 33a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return !AddressIsPoisoned(beg) && 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !AddressIsPoisoned(beg + size - 1) && 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !AddressIsPoisoned(beg + size / 2); 36558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and ASAN_WRITE_RANGE as macro instead of function so 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that no extra frames are created, and stack trace contains 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// relevant information only. 43558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// We check all shadow bytes. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \ 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uptr __offset = (uptr)(offset); \ 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uptr __size = (uptr)(size); \ 47558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch uptr __bad = 0; \ 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!QuickCheckForUnpoisonedRegion(__offset, __size) && \ 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (__bad = __asan_region_is_poisoned(__offset, __size))) { \ 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GET_CURRENT_PC_BP_SP; \ 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asan_report_error(pc, bp, sp, __bad, isWrite, __size); \ 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } while (0) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define ASAN_READ_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size, false) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASAN_WRITE_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size, true) 57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Behavior of functions like "memcpy" or "strcpy" is undefined 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if memory intervals overlap. We report error in this case. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Macro is used to avoid creation of new frames. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline bool RangesOverlap(const char *offset1, uptr length1, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *offset2, uptr length2) { 63558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1)); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \ 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *offset1 = (const char*)_offset1; \ 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char *offset2 = (const char*)_offset2; \ 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (RangesOverlap(offset1, length1, offset2, length2)) { \ 69558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch GET_STACK_TRACE_FATAL_HERE; \ 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \ 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset2, length2, &stack); \ 72558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } \ 73a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} while (0) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#define ENSURE_ASAN_INITED() do { \ 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!asan_init_is_running); \ 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!asan_inited) { \ 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __asan_init(); \ 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} while (0) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if ASAN_INTERCEPT_STRNLEN 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (REAL(strnlen) != 0) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return REAL(strnlen)(s, maxlen); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return internal_strnlen(s, maxlen); 89a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetThreadName(const char *name) { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AsanThread *t = GetCurrentThread(); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (t) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) asanThreadRegistry().SetThreadName(t->tid(), name); 95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 96a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochint OnExit() { 98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // FIXME: ask frontend whether we need to return failure. 99a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return 0; 100a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace __asan 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ---------------------- Wrappers ---------------- {{{1 105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochusing namespace __asan; // NOLINT 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 107558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochDECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define COMMON_INTERCEPTOR_UNPOISON_PARAM(ctx, count) \ 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { \ 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (false) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ 114558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ASAN_WRITE_RANGE(ptr, size) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) ASAN_READ_RANGE(ptr, size) 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch do { \ 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (asan_init_is_running) return REAL(func)(__VA_ARGS__); \ 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctx = 0; \ 120a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch (void) ctx; \ 121a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ENSURE_ASAN_INITED(); \ 122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } while (false) 123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \ 124a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch do { \ 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (false) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \ 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { \ 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } while (false) 129a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \ 130a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch do { \ 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } while (false) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name) 133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name) 134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit() 135a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "sanitizer_common/sanitizer_common_interceptors.inc" 136a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(p, s) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(p, s) 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define COMMON_SYSCALL_POST_READ_RANGE(p, s) \ 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { \ 141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } while (false) 142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \ 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { \ 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (false) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sanitizer_common/sanitizer_common_syscalls.inc" 146558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AsanThread *t = (AsanThread*)arg; 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SetCurrentThread(t); 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return t->ThreadStart(GetTid()); 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if ASAN_INTERCEPT_PTHREAD_CREATE 154558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochextern "C" int pthread_attr_getdetachstate(void *attr, int *v); 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)INTERCEPTOR(int, pthread_create, void *thread, 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void *attr, void *(*start_routine)(void*), void *arg) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnsureMainThreadIDIsCorrect(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Strict init-order checking in thread-hostile. 160558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (flags()->strict_init_order) 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StopInitOrderChecking(); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GET_STACK_TRACE_THREAD; 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int detached = 0; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (attr != 0) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_attr_getdetachstate(attr, &detached); 166558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch u32 current_tid = GetCurrentTidOrInvalid(); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AsanThread *t = AsanThread::Create(start_routine, arg); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateThreadContextArgs args = { t, &stack }; 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) asanThreadRegistry().CreateThread(*(uptr*)t, detached, current_tid, &args); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return REAL(pthread_create)(thread, attr, asan_thread_start, t); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // ASAN_INTERCEPT_PTHREAD_CREATE 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INTERCEPTOR(void*, signal, int signum, void *handler) { 1773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (!AsanInterceptsSignal(signum) || flags()->allow_user_segv_handler) { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return REAL(signal)(signum, handler); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 181} 182 183INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act, 184 struct sigaction *oldact) { 185 if (!AsanInterceptsSignal(signum) || flags()->allow_user_segv_handler) { 186 return REAL(sigaction)(signum, act, oldact); 187 } 188 return 0; 189} 190#elif SANITIZER_POSIX 191// We need to have defined REAL(sigaction) on posix systems. 192DEFINE_REAL(int, sigaction, int signum, const struct sigaction *act, 193 struct sigaction *oldact) 194#endif // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 195 196#if ASAN_INTERCEPT_SWAPCONTEXT 197static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) { 198 // Align to page size. 199 uptr PageSize = GetPageSizeCached(); 200 uptr bottom = stack & ~(PageSize - 1); 201 ssize += stack - bottom; 202 ssize = RoundUpTo(ssize, PageSize); 203 static const uptr kMaxSaneContextStackSize = 1 << 22; // 4 Mb 204 if (ssize && ssize <= kMaxSaneContextStackSize) { 205 PoisonShadow(bottom, ssize, 0); 206 } 207} 208 209INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp, 210 struct ucontext_t *ucp) { 211 static bool reported_warning = false; 212 if (!reported_warning) { 213 Report("WARNING: ASan doesn't fully support makecontext/swapcontext " 214 "functions and may produce false positives in some cases!\n"); 215 reported_warning = true; 216 } 217 // Clear shadow memory for new context (it may share stack 218 // with current context). 219 uptr stack, ssize; 220 ReadContextStack(ucp, &stack, &ssize); 221 ClearShadowMemoryForContextStack(stack, ssize); 222 int res = REAL(swapcontext)(oucp, ucp); 223 // swapcontext technically does not return, but program may swap context to 224 // "oucp" later, that would look as if swapcontext() returned 0. 225 // We need to clear shadow for ucp once again, as it may be in arbitrary 226 // state. 227 ClearShadowMemoryForContextStack(stack, ssize); 228 return res; 229} 230#endif // ASAN_INTERCEPT_SWAPCONTEXT 231 232INTERCEPTOR(void, longjmp, void *env, int val) { 233 __asan_handle_no_return(); 234 REAL(longjmp)(env, val); 235} 236 237#if ASAN_INTERCEPT__LONGJMP 238INTERCEPTOR(void, _longjmp, void *env, int val) { 239 __asan_handle_no_return(); 240 REAL(_longjmp)(env, val); 241} 242#endif 243 244#if ASAN_INTERCEPT_SIGLONGJMP 245INTERCEPTOR(void, siglongjmp, void *env, int val) { 246 __asan_handle_no_return(); 247 REAL(siglongjmp)(env, val); 248} 249#endif 250 251#if ASAN_INTERCEPT___CXA_THROW 252INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { 253 CHECK(REAL(__cxa_throw)); 254 __asan_handle_no_return(); 255 REAL(__cxa_throw)(a, b, c); 256} 257#endif 258 259// intercept mlock and friends. 260// Since asan maps 16T of RAM, mlock is completely unfriendly to asan. 261// All functions return 0 (success). 262static void MlockIsUnsupported() { 263 static bool printed = false; 264 if (printed) return; 265 printed = true; 266 if (flags()->verbosity > 0) { 267 Printf("INFO: AddressSanitizer ignores " 268 "mlock/mlockall/munlock/munlockall\n"); 269 } 270} 271 272INTERCEPTOR(int, mlock, const void *addr, uptr len) { 273 MlockIsUnsupported(); 274 return 0; 275} 276 277INTERCEPTOR(int, munlock, const void *addr, uptr len) { 278 MlockIsUnsupported(); 279 return 0; 280} 281 282INTERCEPTOR(int, mlockall, int flags) { 283 MlockIsUnsupported(); 284 return 0; 285} 286 287INTERCEPTOR(int, munlockall, void) { 288 MlockIsUnsupported(); 289 return 0; 290} 291 292static inline int CharCmp(unsigned char c1, unsigned char c2) { 293 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 294} 295 296INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { 297 if (!asan_inited) return internal_memcmp(a1, a2, size); 298 ENSURE_ASAN_INITED(); 299 if (flags()->replace_intrin) { 300 if (flags()->strict_memcmp) { 301 // Check the entire regions even if the first bytes of the buffers are 302 // different. 303 ASAN_READ_RANGE(a1, size); 304 ASAN_READ_RANGE(a2, size); 305 // Fallthrough to REAL(memcmp) below. 306 } else { 307 unsigned char c1 = 0, c2 = 0; 308 const unsigned char *s1 = (const unsigned char*)a1; 309 const unsigned char *s2 = (const unsigned char*)a2; 310 uptr i; 311 for (i = 0; i < size; i++) { 312 c1 = s1[i]; 313 c2 = s2[i]; 314 if (c1 != c2) break; 315 } 316 ASAN_READ_RANGE(s1, Min(i + 1, size)); 317 ASAN_READ_RANGE(s2, Min(i + 1, size)); 318 return CharCmp(c1, c2); 319 } 320 } 321 return REAL(memcmp(a1, a2, size)); 322} 323 324#define MEMMOVE_BODY { \ 325 if (!asan_inited) return internal_memmove(to, from, size); \ 326 if (asan_init_is_running) { \ 327 return REAL(memmove)(to, from, size); \ 328 } \ 329 ENSURE_ASAN_INITED(); \ 330 if (flags()->replace_intrin) { \ 331 ASAN_READ_RANGE(from, size); \ 332 ASAN_WRITE_RANGE(to, size); \ 333 } \ 334 return internal_memmove(to, from, size); \ 335} 336 337INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) MEMMOVE_BODY 338 339INTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) { 340#if !SANITIZER_MAC 341 if (!asan_inited) return internal_memcpy(to, from, size); 342 // memcpy is called during __asan_init() from the internals 343 // of printf(...). 344 if (asan_init_is_running) { 345 return REAL(memcpy)(to, from, size); 346 } 347 ENSURE_ASAN_INITED(); 348 if (flags()->replace_intrin) { 349 if (to != from) { 350 // We do not treat memcpy with to==from as a bug. 351 // See http://llvm.org/bugs/show_bug.cgi?id=11763. 352 CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); 353 } 354 ASAN_READ_RANGE(from, size); 355 ASAN_WRITE_RANGE(to, size); 356 } 357 // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8, so 358 // calling REAL(memcpy) here leads to infinite recursion. 359 // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116. 360 return internal_memcpy(to, from, size); 361#else 362 // At least on 10.7 and 10.8 both memcpy() and memmove() are being replaced 363 // with WRAP(memcpy). As a result, false positives are reported for memmove() 364 // calls. If we just disable error reporting with 365 // ASAN_OPTIONS=replace_intrin=0, memmove() is still replaced with 366 // internal_memcpy(), which may lead to crashes, see 367 // http://llvm.org/bugs/show_bug.cgi?id=16362. 368 MEMMOVE_BODY 369#endif // !SANITIZER_MAC 370} 371 372INTERCEPTOR(void*, memset, void *block, int c, uptr size) { 373 if (!asan_inited) return internal_memset(block, c, size); 374 // memset is called inside Printf. 375 if (asan_init_is_running) { 376 return REAL(memset)(block, c, size); 377 } 378 ENSURE_ASAN_INITED(); 379 if (flags()->replace_intrin) { 380 ASAN_WRITE_RANGE(block, size); 381 } 382 return REAL(memset)(block, c, size); 383} 384 385INTERCEPTOR(char*, strchr, const char *str, int c) { 386 if (!asan_inited) return internal_strchr(str, c); 387 // strchr is called inside create_purgeable_zone() when MallocGuardEdges=1 is 388 // used. 389 if (asan_init_is_running) { 390 return REAL(strchr)(str, c); 391 } 392 ENSURE_ASAN_INITED(); 393 char *result = REAL(strchr)(str, c); 394 if (flags()->replace_str) { 395 uptr bytes_read = (result ? result - str : REAL(strlen)(str)) + 1; 396 ASAN_READ_RANGE(str, bytes_read); 397 } 398 return result; 399} 400 401#if ASAN_INTERCEPT_INDEX 402# if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 403INTERCEPTOR(char*, index, const char *string, int c) 404 ALIAS(WRAPPER_NAME(strchr)); 405# else 406# if SANITIZER_MAC 407DECLARE_REAL(char*, index, const char *string, int c) 408OVERRIDE_FUNCTION(index, strchr); 409# else 410DEFINE_REAL(char*, index, const char *string, int c) 411# endif 412# endif 413#endif // ASAN_INTERCEPT_INDEX 414 415// For both strcat() and strncat() we need to check the validity of |to| 416// argument irrespective of the |from| length. 417INTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT 418 ENSURE_ASAN_INITED(); 419 if (flags()->replace_str) { 420 uptr from_length = REAL(strlen)(from); 421 ASAN_READ_RANGE(from, from_length + 1); 422 uptr to_length = REAL(strlen)(to); 423 ASAN_READ_RANGE(to, to_length); 424 ASAN_WRITE_RANGE(to + to_length, from_length + 1); 425 // If the copying actually happens, the |from| string should not overlap 426 // with the resulting string starting at |to|, which has a length of 427 // to_length + from_length + 1. 428 if (from_length > 0) { 429 CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1, 430 from, from_length + 1); 431 } 432 } 433 return REAL(strcat)(to, from); // NOLINT 434} 435 436INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) { 437 ENSURE_ASAN_INITED(); 438 if (flags()->replace_str) { 439 uptr from_length = MaybeRealStrnlen(from, size); 440 uptr copy_length = Min(size, from_length + 1); 441 ASAN_READ_RANGE(from, copy_length); 442 uptr to_length = REAL(strlen)(to); 443 ASAN_READ_RANGE(to, to_length); 444 ASAN_WRITE_RANGE(to + to_length, from_length + 1); 445 if (from_length > 0) { 446 CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1, 447 from, copy_length); 448 } 449 } 450 return REAL(strncat)(to, from, size); 451} 452 453INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT 454#if SANITIZER_MAC 455 if (!asan_inited) return REAL(strcpy)(to, from); // NOLINT 456#endif 457 // strcpy is called from malloc_default_purgeable_zone() 458 // in __asan::ReplaceSystemAlloc() on Mac. 459 if (asan_init_is_running) { 460 return REAL(strcpy)(to, from); // NOLINT 461 } 462 ENSURE_ASAN_INITED(); 463 if (flags()->replace_str) { 464 uptr from_size = REAL(strlen)(from) + 1; 465 CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size); 466 ASAN_READ_RANGE(from, from_size); 467 ASAN_WRITE_RANGE(to, from_size); 468 } 469 return REAL(strcpy)(to, from); // NOLINT 470} 471 472#if ASAN_INTERCEPT_STRDUP 473INTERCEPTOR(char*, strdup, const char *s) { 474 if (!asan_inited) return internal_strdup(s); 475 ENSURE_ASAN_INITED(); 476 uptr length = REAL(strlen)(s); 477 if (flags()->replace_str) { 478 ASAN_READ_RANGE(s, length + 1); 479 } 480 GET_STACK_TRACE_MALLOC; 481 void *new_mem = asan_malloc(length + 1, &stack); 482 REAL(memcpy)(new_mem, s, length + 1); 483 return reinterpret_cast<char*>(new_mem); 484} 485#endif 486 487INTERCEPTOR(uptr, strlen, const char *s) { 488 if (!asan_inited) return internal_strlen(s); 489 // strlen is called from malloc_default_purgeable_zone() 490 // in __asan::ReplaceSystemAlloc() on Mac. 491 if (asan_init_is_running) { 492 return REAL(strlen)(s); 493 } 494 ENSURE_ASAN_INITED(); 495 uptr length = REAL(strlen)(s); 496 if (flags()->replace_str) { 497 ASAN_READ_RANGE(s, length + 1); 498 } 499 return length; 500} 501 502INTERCEPTOR(uptr, wcslen, const wchar_t *s) { 503 uptr length = REAL(wcslen)(s); 504 if (!asan_init_is_running) { 505 ENSURE_ASAN_INITED(); 506 ASAN_READ_RANGE(s, (length + 1) * sizeof(wchar_t)); 507 } 508 return length; 509} 510 511INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) { 512 ENSURE_ASAN_INITED(); 513 if (flags()->replace_str) { 514 uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1); 515 CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size); 516 ASAN_READ_RANGE(from, from_size); 517 ASAN_WRITE_RANGE(to, size); 518 } 519 return REAL(strncpy)(to, from, size); 520} 521 522#if ASAN_INTERCEPT_STRNLEN 523INTERCEPTOR(uptr, strnlen, const char *s, uptr maxlen) { 524 ENSURE_ASAN_INITED(); 525 uptr length = REAL(strnlen)(s, maxlen); 526 if (flags()->replace_str) { 527 ASAN_READ_RANGE(s, Min(length + 1, maxlen)); 528 } 529 return length; 530} 531#endif // ASAN_INTERCEPT_STRNLEN 532 533static inline bool IsValidStrtolBase(int base) { 534 return (base == 0) || (2 <= base && base <= 36); 535} 536 537static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) { 538 CHECK(endptr); 539 if (nptr == *endptr) { 540 // No digits were found at strtol call, we need to find out the last 541 // symbol accessed by strtoll on our own. 542 // We get this symbol by skipping leading blanks and optional +/- sign. 543 while (IsSpace(*nptr)) nptr++; 544 if (*nptr == '+' || *nptr == '-') nptr++; 545 *endptr = (char*)nptr; 546 } 547 CHECK(*endptr >= nptr); 548} 549 550INTERCEPTOR(long, strtol, const char *nptr, // NOLINT 551 char **endptr, int base) { 552 ENSURE_ASAN_INITED(); 553 if (!flags()->replace_str) { 554 return REAL(strtol)(nptr, endptr, base); 555 } 556 char *real_endptr; 557 long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT 558 if (endptr != 0) { 559 *endptr = real_endptr; 560 } 561 if (IsValidStrtolBase(base)) { 562 FixRealStrtolEndptr(nptr, &real_endptr); 563 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 564 } 565 return result; 566} 567 568INTERCEPTOR(int, atoi, const char *nptr) { 569#if SANITIZER_MAC 570 if (!asan_inited) return REAL(atoi)(nptr); 571#endif 572 ENSURE_ASAN_INITED(); 573 if (!flags()->replace_str) { 574 return REAL(atoi)(nptr); 575 } 576 char *real_endptr; 577 // "man atoi" tells that behavior of atoi(nptr) is the same as 578 // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the 579 // parsed integer can't be stored in *long* type (even if it's 580 // different from int). So, we just imitate this behavior. 581 int result = REAL(strtol)(nptr, &real_endptr, 10); 582 FixRealStrtolEndptr(nptr, &real_endptr); 583 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 584 return result; 585} 586 587INTERCEPTOR(long, atol, const char *nptr) { // NOLINT 588#if SANITIZER_MAC 589 if (!asan_inited) return REAL(atol)(nptr); 590#endif 591 ENSURE_ASAN_INITED(); 592 if (!flags()->replace_str) { 593 return REAL(atol)(nptr); 594 } 595 char *real_endptr; 596 long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT 597 FixRealStrtolEndptr(nptr, &real_endptr); 598 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 599 return result; 600} 601 602#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 603INTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT 604 char **endptr, int base) { 605 ENSURE_ASAN_INITED(); 606 if (!flags()->replace_str) { 607 return REAL(strtoll)(nptr, endptr, base); 608 } 609 char *real_endptr; 610 long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT 611 if (endptr != 0) { 612 *endptr = real_endptr; 613 } 614 // If base has unsupported value, strtoll can exit with EINVAL 615 // without reading any characters. So do additional checks only 616 // if base is valid. 617 if (IsValidStrtolBase(base)) { 618 FixRealStrtolEndptr(nptr, &real_endptr); 619 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 620 } 621 return result; 622} 623 624INTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT 625 ENSURE_ASAN_INITED(); 626 if (!flags()->replace_str) { 627 return REAL(atoll)(nptr); 628 } 629 char *real_endptr; 630 long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT 631 FixRealStrtolEndptr(nptr, &real_endptr); 632 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 633 return result; 634} 635#endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL 636 637static void AtCxaAtexit(void *unused) { 638 (void)unused; 639 StopInitOrderChecking(); 640} 641 642#if ASAN_INTERCEPT___CXA_ATEXIT 643INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, 644 void *dso_handle) { 645 ENSURE_ASAN_INITED(); 646 int res = REAL(__cxa_atexit)(func, arg, dso_handle); 647 REAL(__cxa_atexit)(AtCxaAtexit, 0, 0); 648 return res; 649} 650#endif // ASAN_INTERCEPT___CXA_ATEXIT 651 652#if !SANITIZER_MAC 653#define ASAN_INTERCEPT_FUNC(name) do { \ 654 if (!INTERCEPT_FUNCTION(name) && flags()->verbosity > 0) \ 655 Report("AddressSanitizer: failed to intercept '" #name "'\n"); \ 656 } while (0) 657#else 658// OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION. 659#define ASAN_INTERCEPT_FUNC(name) 660#endif // SANITIZER_MAC 661 662#if SANITIZER_WINDOWS 663INTERCEPTOR_WINAPI(DWORD, CreateThread, 664 void* security, uptr stack_size, 665 DWORD (__stdcall *start_routine)(void*), void* arg, 666 DWORD thr_flags, void* tid) { 667 // Strict init-order checking in thread-hostile. 668 if (flags()->strict_init_order) 669 StopInitOrderChecking(); 670 GET_STACK_TRACE_THREAD; 671 u32 current_tid = GetCurrentTidOrInvalid(); 672 AsanThread *t = AsanThread::Create(start_routine, arg); 673 CreateThreadContextArgs args = { t, &stack }; 674 bool detached = false; // FIXME: how can we determine it on Windows? 675 asanThreadRegistry().CreateThread(*(uptr*)t, detached, current_tid, &args); 676 return REAL(CreateThread)(security, stack_size, 677 asan_thread_start, t, thr_flags, tid); 678} 679 680namespace __asan { 681void InitializeWindowsInterceptors() { 682 ASAN_INTERCEPT_FUNC(CreateThread); 683} 684 685} // namespace __asan 686#endif 687 688// ---------------------- InitializeAsanInterceptors ---------------- {{{1 689namespace __asan { 690void InitializeAsanInterceptors() { 691 static bool was_called_once; 692 CHECK(was_called_once == false); 693 was_called_once = true; 694 SANITIZER_COMMON_INTERCEPTORS_INIT; 695 696 // Intercept mem* functions. 697 ASAN_INTERCEPT_FUNC(memcmp); 698 ASAN_INTERCEPT_FUNC(memmove); 699 ASAN_INTERCEPT_FUNC(memset); 700 if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { 701 ASAN_INTERCEPT_FUNC(memcpy); 702 } 703 704 // Intercept str* functions. 705 ASAN_INTERCEPT_FUNC(strcat); // NOLINT 706 ASAN_INTERCEPT_FUNC(strchr); 707 ASAN_INTERCEPT_FUNC(strcpy); // NOLINT 708 ASAN_INTERCEPT_FUNC(strlen); 709 ASAN_INTERCEPT_FUNC(wcslen); 710 ASAN_INTERCEPT_FUNC(strncat); 711 ASAN_INTERCEPT_FUNC(strncpy); 712#if ASAN_INTERCEPT_STRDUP 713 ASAN_INTERCEPT_FUNC(strdup); 714#endif 715#if ASAN_INTERCEPT_STRNLEN 716 ASAN_INTERCEPT_FUNC(strnlen); 717#endif 718#if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 719 ASAN_INTERCEPT_FUNC(index); 720#endif 721 722 ASAN_INTERCEPT_FUNC(atoi); 723 ASAN_INTERCEPT_FUNC(atol); 724 ASAN_INTERCEPT_FUNC(strtol); 725#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 726 ASAN_INTERCEPT_FUNC(atoll); 727 ASAN_INTERCEPT_FUNC(strtoll); 728#endif 729 730#if ASAN_INTERCEPT_MLOCKX 731 // Intercept mlock/munlock. 732 ASAN_INTERCEPT_FUNC(mlock); 733 ASAN_INTERCEPT_FUNC(munlock); 734 ASAN_INTERCEPT_FUNC(mlockall); 735 ASAN_INTERCEPT_FUNC(munlockall); 736#endif 737 738 // Intecept signal- and jump-related functions. 739 ASAN_INTERCEPT_FUNC(longjmp); 740#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 741 ASAN_INTERCEPT_FUNC(sigaction); 742 ASAN_INTERCEPT_FUNC(signal); 743#endif 744#if ASAN_INTERCEPT_SWAPCONTEXT 745 ASAN_INTERCEPT_FUNC(swapcontext); 746#endif 747#if ASAN_INTERCEPT__LONGJMP 748 ASAN_INTERCEPT_FUNC(_longjmp); 749#endif 750#if ASAN_INTERCEPT_SIGLONGJMP 751 ASAN_INTERCEPT_FUNC(siglongjmp); 752#endif 753 754 // Intercept exception handling functions. 755#if ASAN_INTERCEPT___CXA_THROW 756 INTERCEPT_FUNCTION(__cxa_throw); 757#endif 758 759 // Intercept threading-related functions 760#if ASAN_INTERCEPT_PTHREAD_CREATE 761 ASAN_INTERCEPT_FUNC(pthread_create); 762#endif 763 764 // Intercept atexit function. 765#if ASAN_INTERCEPT___CXA_ATEXIT 766 ASAN_INTERCEPT_FUNC(__cxa_atexit); 767#endif 768 769 // Some Windows-specific interceptors. 770#if SANITIZER_WINDOWS 771 InitializeWindowsInterceptors(); 772#endif 773 774 if (flags()->verbosity > 0) { 775 Report("AddressSanitizer: libc interceptors initialized\n"); 776 } 777} 778 779} // namespace __asan 780