asan_interceptors.cc revision b9a928497168e177791f10f5042ff6f5e4e8a881
1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//===-- asan_interceptors.cc ----------------------------------------------===// 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// The LLVM Compiler Infrastructure 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// License. See LICENSE.TXT for details. 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//===----------------------------------------------------------------------===// 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This file is a part of AddressSanitizer, an address sanity checker. 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Intercept various libc functions. 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//===----------------------------------------------------------------------===// 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "asan_interceptors.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "asan_allocator.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "asan_intercepted_functions.h" 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "asan_internal.h" 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "asan_mapping.h" 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "asan_poisoning.h" 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "asan_report.h" 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "asan_stack.h" 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "asan_stats.h" 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "interception/interception.h" 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "sanitizer_common/sanitizer_libc.h" 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 27e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochnamespace __asan { 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Return true if we can quickly decide that the region is unpoisoned. 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static inline bool QuickCheckForUnpoisonedRegion(uptr beg, uptr size) { 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (size == 0) return true; 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (size <= 32) 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return !AddressIsPoisoned(beg) && 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !AddressIsPoisoned(beg + size - 1) && 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !AddressIsPoisoned(beg + size / 2); 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE, 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// and ASAN_WRITE_RANGE as macro instead of function so 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// that no extra frames are created, and stack trace contains 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// relevant information only. 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// We check all shadow bytes. 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \ 457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) uptr __offset = (uptr)(offset); \ 467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) uptr __size = (uptr)(size); \ 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) uptr __bad = 0; \ 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!QuickCheckForUnpoisonedRegion(__offset, __size) && \ 49e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch (__bad = __asan_region_is_poisoned(__offset, __size))) { \ 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GET_CURRENT_PC_BP_SP; \ 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) __asan_report_error(pc, bp, sp, __bad, isWrite, __size); \ 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } \ 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } while (0) 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define ASAN_READ_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size, false) 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define ASAN_WRITE_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size, true) 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Behavior of functions like "memcpy" or "strcpy" is undefined 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// if memory intervals overlap. We report error in this case. 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Macro is used to avoid creation of new frames. 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static inline bool RangesOverlap(const char *offset1, uptr length1, 62 const char *offset2, uptr length2) { 63 return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1)); 64} 65#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \ 66 const char *offset1 = (const char*)_offset1; \ 67 const char *offset2 = (const char*)_offset2; \ 68 if (RangesOverlap(offset1, length1, offset2, length2)) { \ 69 GET_STACK_TRACE_FATAL_HERE; \ 70 ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \ 71 offset2, length2, &stack); \ 72 } \ 73} while (0) 74 75#define ENSURE_ASAN_INITED() do { \ 76 CHECK(!asan_init_is_running); \ 77 if (!asan_inited) { \ 78 __asan_init(); \ 79 } \ 80} while (0) 81 82static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) { 83#if ASAN_INTERCEPT_STRNLEN 84 if (REAL(strnlen) != 0) { 85 return REAL(strnlen)(s, maxlen); 86 } 87#endif 88 return internal_strnlen(s, maxlen); 89} 90 91void SetThreadName(const char *name) { 92 AsanThread *t = GetCurrentThread(); 93 if (t) 94 asanThreadRegistry().SetThreadName(t->tid(), name); 95} 96 97} // namespace __asan 98 99// ---------------------- Wrappers ---------------- {{{1 100using namespace __asan; // NOLINT 101 102#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ 103 ASAN_WRITE_RANGE(ptr, size) 104#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) ASAN_READ_RANGE(ptr, size) 105#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ 106 do { \ 107 if (asan_init_is_running) return REAL(func)(__VA_ARGS__); \ 108 ctx = 0; \ 109 (void) ctx; \ 110 ENSURE_ASAN_INITED(); \ 111 } while (false) 112#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \ 113 do { \ 114 } while (false) 115#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \ 116 do { \ 117 } while (false) 118#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \ 119 do { \ 120 } while (false) 121#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name) 122#include "sanitizer_common/sanitizer_common_interceptors.inc" 123 124#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(p, s) 125#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(p, s) 126#define COMMON_SYSCALL_POST_READ_RANGE(p, s) 127#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) 128#include "sanitizer_common/sanitizer_common_syscalls.inc" 129 130static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { 131 AsanThread *t = (AsanThread*)arg; 132 SetCurrentThread(t); 133 return t->ThreadStart(GetTid()); 134} 135 136#if ASAN_INTERCEPT_PTHREAD_CREATE 137extern "C" int pthread_attr_getdetachstate(void *attr, int *v); 138 139INTERCEPTOR(int, pthread_create, void *thread, 140 void *attr, void *(*start_routine)(void*), void *arg) { 141 // Strict init-order checking in thread-hostile. 142 if (flags()->strict_init_order) 143 StopInitOrderChecking(); 144 GET_STACK_TRACE_THREAD; 145 int detached = 0; 146 if (attr != 0) 147 pthread_attr_getdetachstate(attr, &detached); 148 149 u32 current_tid = GetCurrentTidOrInvalid(); 150 AsanThread *t = AsanThread::Create(start_routine, arg); 151 CreateThreadContextArgs args = { t, &stack }; 152 asanThreadRegistry().CreateThread(*(uptr*)t, detached, current_tid, &args); 153 return REAL(pthread_create)(thread, attr, asan_thread_start, t); 154} 155#endif // ASAN_INTERCEPT_PTHREAD_CREATE 156 157#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 158INTERCEPTOR(void*, signal, int signum, void *handler) { 159 if (!AsanInterceptsSignal(signum) || flags()->allow_user_segv_handler) { 160 return REAL(signal)(signum, handler); 161 } 162 return 0; 163} 164 165INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act, 166 struct sigaction *oldact) { 167 if (!AsanInterceptsSignal(signum) || flags()->allow_user_segv_handler) { 168 return REAL(sigaction)(signum, act, oldact); 169 } 170 return 0; 171} 172#elif SANITIZER_POSIX 173// We need to have defined REAL(sigaction) on posix systems. 174DEFINE_REAL(int, sigaction, int signum, const struct sigaction *act, 175 struct sigaction *oldact) 176#endif // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 177 178#if ASAN_INTERCEPT_SWAPCONTEXT 179static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) { 180 // Align to page size. 181 uptr PageSize = GetPageSizeCached(); 182 uptr bottom = stack & ~(PageSize - 1); 183 ssize += stack - bottom; 184 ssize = RoundUpTo(ssize, PageSize); 185 static const uptr kMaxSaneContextStackSize = 1 << 22; // 4 Mb 186 if (ssize && ssize <= kMaxSaneContextStackSize) { 187 PoisonShadow(bottom, ssize, 0); 188 } 189} 190 191INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp, 192 struct ucontext_t *ucp) { 193 static bool reported_warning = false; 194 if (!reported_warning) { 195 Report("WARNING: ASan doesn't fully support makecontext/swapcontext " 196 "functions and may produce false positives in some cases!\n"); 197 reported_warning = true; 198 } 199 // Clear shadow memory for new context (it may share stack 200 // with current context). 201 uptr stack, ssize; 202 ReadContextStack(ucp, &stack, &ssize); 203 ClearShadowMemoryForContextStack(stack, ssize); 204 int res = REAL(swapcontext)(oucp, ucp); 205 // swapcontext technically does not return, but program may swap context to 206 // "oucp" later, that would look as if swapcontext() returned 0. 207 // We need to clear shadow for ucp once again, as it may be in arbitrary 208 // state. 209 ClearShadowMemoryForContextStack(stack, ssize); 210 return res; 211} 212#endif // ASAN_INTERCEPT_SWAPCONTEXT 213 214INTERCEPTOR(void, longjmp, void *env, int val) { 215 __asan_handle_no_return(); 216 REAL(longjmp)(env, val); 217} 218 219#if ASAN_INTERCEPT__LONGJMP 220INTERCEPTOR(void, _longjmp, void *env, int val) { 221 __asan_handle_no_return(); 222 REAL(_longjmp)(env, val); 223} 224#endif 225 226#if ASAN_INTERCEPT_SIGLONGJMP 227INTERCEPTOR(void, siglongjmp, void *env, int val) { 228 __asan_handle_no_return(); 229 REAL(siglongjmp)(env, val); 230} 231#endif 232 233#if ASAN_INTERCEPT___CXA_THROW 234INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { 235 CHECK(REAL(__cxa_throw)); 236 __asan_handle_no_return(); 237 REAL(__cxa_throw)(a, b, c); 238} 239#endif 240 241// intercept mlock and friends. 242// Since asan maps 16T of RAM, mlock is completely unfriendly to asan. 243// All functions return 0 (success). 244static void MlockIsUnsupported() { 245 static bool printed = false; 246 if (printed) return; 247 printed = true; 248 if (flags()->verbosity > 0) 249 Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n"); 250} 251 252INTERCEPTOR(int, mlock, const void *addr, uptr len) { 253 MlockIsUnsupported(); 254 return 0; 255} 256 257INTERCEPTOR(int, munlock, const void *addr, uptr len) { 258 MlockIsUnsupported(); 259 return 0; 260} 261 262INTERCEPTOR(int, mlockall, int flags) { 263 MlockIsUnsupported(); 264 return 0; 265} 266 267INTERCEPTOR(int, munlockall, void) { 268 MlockIsUnsupported(); 269 return 0; 270} 271 272static inline int CharCmp(unsigned char c1, unsigned char c2) { 273 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 274} 275 276INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { 277 if (!asan_inited) return internal_memcmp(a1, a2, size); 278 ENSURE_ASAN_INITED(); 279 if (flags()->replace_intrin) { 280 if (flags()->strict_memcmp) { 281 // Check the entire regions even if the first bytes of the buffers are 282 // different. 283 ASAN_READ_RANGE(a1, size); 284 ASAN_READ_RANGE(a2, size); 285 // Fallthrough to REAL(memcmp) below. 286 } else { 287 unsigned char c1 = 0, c2 = 0; 288 const unsigned char *s1 = (const unsigned char*)a1; 289 const unsigned char *s2 = (const unsigned char*)a2; 290 uptr i; 291 for (i = 0; i < size; i++) { 292 c1 = s1[i]; 293 c2 = s2[i]; 294 if (c1 != c2) break; 295 } 296 ASAN_READ_RANGE(s1, Min(i + 1, size)); 297 ASAN_READ_RANGE(s2, Min(i + 1, size)); 298 return CharCmp(c1, c2); 299 } 300 } 301 return REAL(memcmp(a1, a2, size)); 302} 303 304INTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) { 305 if (!asan_inited) return internal_memcpy(to, from, size); 306 // memcpy is called during __asan_init() from the internals 307 // of printf(...). 308 if (asan_init_is_running) { 309 return REAL(memcpy)(to, from, size); 310 } 311 ENSURE_ASAN_INITED(); 312 if (flags()->replace_intrin) { 313 if (to != from) { 314 // We do not treat memcpy with to==from as a bug. 315 // See http://llvm.org/bugs/show_bug.cgi?id=11763. 316 CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); 317 } 318 ASAN_READ_RANGE(from, size); 319 ASAN_WRITE_RANGE(to, size); 320 } 321 // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8. 322 // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116. 323 return internal_memcpy(to, from, size); 324} 325 326INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) { 327 if (!asan_inited) return internal_memmove(to, from, size); 328 if (asan_init_is_running) { 329 return REAL(memmove)(to, from, size); 330 } 331 ENSURE_ASAN_INITED(); 332 if (flags()->replace_intrin) { 333 ASAN_READ_RANGE(from, size); 334 ASAN_WRITE_RANGE(to, size); 335 } 336 // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8. 337 // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116. 338 return internal_memmove(to, from, size); 339} 340 341INTERCEPTOR(void*, memset, void *block, int c, uptr size) { 342 if (!asan_inited) return internal_memset(block, c, size); 343 // memset is called inside Printf. 344 if (asan_init_is_running) { 345 return REAL(memset)(block, c, size); 346 } 347 ENSURE_ASAN_INITED(); 348 if (flags()->replace_intrin) { 349 ASAN_WRITE_RANGE(block, size); 350 } 351 return REAL(memset)(block, c, size); 352} 353 354INTERCEPTOR(char*, strchr, const char *str, int c) { 355 if (!asan_inited) return internal_strchr(str, c); 356 // strchr is called inside create_purgeable_zone() when MallocGuardEdges=1 is 357 // used. 358 if (asan_init_is_running) { 359 return REAL(strchr)(str, c); 360 } 361 ENSURE_ASAN_INITED(); 362 char *result = REAL(strchr)(str, c); 363 if (flags()->replace_str) { 364 uptr bytes_read = (result ? result - str : REAL(strlen)(str)) + 1; 365 ASAN_READ_RANGE(str, bytes_read); 366 } 367 return result; 368} 369 370#if ASAN_INTERCEPT_INDEX 371# if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 372INTERCEPTOR(char*, index, const char *string, int c) 373 ALIAS(WRAPPER_NAME(strchr)); 374# else 375# if SANITIZER_MAC 376DECLARE_REAL(char*, index, const char *string, int c) 377OVERRIDE_FUNCTION(index, strchr); 378# else 379DEFINE_REAL(char*, index, const char *string, int c) 380# endif 381# endif 382#endif // ASAN_INTERCEPT_INDEX 383 384// For both strcat() and strncat() we need to check the validity of |to| 385// argument irrespective of the |from| length. 386INTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT 387 ENSURE_ASAN_INITED(); 388 if (flags()->replace_str) { 389 uptr from_length = REAL(strlen)(from); 390 ASAN_READ_RANGE(from, from_length + 1); 391 uptr to_length = REAL(strlen)(to); 392 ASAN_READ_RANGE(to, to_length); 393 ASAN_WRITE_RANGE(to + to_length, from_length + 1); 394 // If the copying actually happens, the |from| string should not overlap 395 // with the resulting string starting at |to|, which has a length of 396 // to_length + from_length + 1. 397 if (from_length > 0) { 398 CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1, 399 from, from_length + 1); 400 } 401 } 402 return REAL(strcat)(to, from); // NOLINT 403} 404 405INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) { 406 ENSURE_ASAN_INITED(); 407 if (flags()->replace_str) { 408 uptr from_length = MaybeRealStrnlen(from, size); 409 uptr copy_length = Min(size, from_length + 1); 410 ASAN_READ_RANGE(from, copy_length); 411 uptr to_length = REAL(strlen)(to); 412 ASAN_READ_RANGE(to, to_length); 413 ASAN_WRITE_RANGE(to + to_length, from_length + 1); 414 if (from_length > 0) { 415 CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1, 416 from, copy_length); 417 } 418 } 419 return REAL(strncat)(to, from, size); 420} 421 422INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 423 if (!asan_inited) return internal_strcmp(s1, s2); 424 if (asan_init_is_running) { 425 return REAL(strcmp)(s1, s2); 426 } 427 ENSURE_ASAN_INITED(); 428 unsigned char c1, c2; 429 uptr i; 430 for (i = 0; ; i++) { 431 c1 = (unsigned char)s1[i]; 432 c2 = (unsigned char)s2[i]; 433 if (c1 != c2 || c1 == '\0') break; 434 } 435 ASAN_READ_RANGE(s1, i + 1); 436 ASAN_READ_RANGE(s2, i + 1); 437 return CharCmp(c1, c2); 438} 439 440INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT 441#if SANITIZER_MAC 442 if (!asan_inited) return REAL(strcpy)(to, from); // NOLINT 443#endif 444 // strcpy is called from malloc_default_purgeable_zone() 445 // in __asan::ReplaceSystemAlloc() on Mac. 446 if (asan_init_is_running) { 447 return REAL(strcpy)(to, from); // NOLINT 448 } 449 ENSURE_ASAN_INITED(); 450 if (flags()->replace_str) { 451 uptr from_size = REAL(strlen)(from) + 1; 452 CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size); 453 ASAN_READ_RANGE(from, from_size); 454 ASAN_WRITE_RANGE(to, from_size); 455 } 456 return REAL(strcpy)(to, from); // NOLINT 457} 458 459#if ASAN_INTERCEPT_STRDUP 460INTERCEPTOR(char*, strdup, const char *s) { 461 if (!asan_inited) return internal_strdup(s); 462 ENSURE_ASAN_INITED(); 463 uptr length = REAL(strlen)(s); 464 if (flags()->replace_str) { 465 ASAN_READ_RANGE(s, length + 1); 466 } 467 GET_STACK_TRACE_MALLOC; 468 void *new_mem = asan_malloc(length + 1, &stack); 469 REAL(memcpy)(new_mem, s, length + 1); 470 return reinterpret_cast<char*>(new_mem); 471} 472#endif 473 474INTERCEPTOR(uptr, strlen, const char *s) { 475 if (!asan_inited) return internal_strlen(s); 476 // strlen is called from malloc_default_purgeable_zone() 477 // in __asan::ReplaceSystemAlloc() on Mac. 478 if (asan_init_is_running) { 479 return REAL(strlen)(s); 480 } 481 ENSURE_ASAN_INITED(); 482 uptr length = REAL(strlen)(s); 483 if (flags()->replace_str) { 484 ASAN_READ_RANGE(s, length + 1); 485 } 486 return length; 487} 488 489INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { 490 if (!asan_inited) return internal_strncmp(s1, s2, size); 491 // strncmp is called from malloc_default_purgeable_zone() 492 // in __asan::ReplaceSystemAlloc() on Mac. 493 if (asan_init_is_running) { 494 return REAL(strncmp)(s1, s2, size); 495 } 496 ENSURE_ASAN_INITED(); 497 unsigned char c1 = 0, c2 = 0; 498 uptr i; 499 for (i = 0; i < size; i++) { 500 c1 = (unsigned char)s1[i]; 501 c2 = (unsigned char)s2[i]; 502 if (c1 != c2 || c1 == '\0') break; 503 } 504 ASAN_READ_RANGE(s1, Min(i + 1, size)); 505 ASAN_READ_RANGE(s2, Min(i + 1, size)); 506 return CharCmp(c1, c2); 507} 508 509INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) { 510 ENSURE_ASAN_INITED(); 511 if (flags()->replace_str) { 512 uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1); 513 CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size); 514 ASAN_READ_RANGE(from, from_size); 515 ASAN_WRITE_RANGE(to, size); 516 } 517 return REAL(strncpy)(to, from, size); 518} 519 520#if ASAN_INTERCEPT_STRNLEN 521INTERCEPTOR(uptr, strnlen, const char *s, uptr maxlen) { 522 ENSURE_ASAN_INITED(); 523 uptr length = REAL(strnlen)(s, maxlen); 524 if (flags()->replace_str) { 525 ASAN_READ_RANGE(s, Min(length + 1, maxlen)); 526 } 527 return length; 528} 529#endif // ASAN_INTERCEPT_STRNLEN 530 531static inline bool IsValidStrtolBase(int base) { 532 return (base == 0) || (2 <= base && base <= 36); 533} 534 535static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) { 536 CHECK(endptr); 537 if (nptr == *endptr) { 538 // No digits were found at strtol call, we need to find out the last 539 // symbol accessed by strtoll on our own. 540 // We get this symbol by skipping leading blanks and optional +/- sign. 541 while (IsSpace(*nptr)) nptr++; 542 if (*nptr == '+' || *nptr == '-') nptr++; 543 *endptr = (char*)nptr; 544 } 545 CHECK(*endptr >= nptr); 546} 547 548INTERCEPTOR(long, strtol, const char *nptr, // NOLINT 549 char **endptr, int base) { 550 ENSURE_ASAN_INITED(); 551 if (!flags()->replace_str) { 552 return REAL(strtol)(nptr, endptr, base); 553 } 554 char *real_endptr; 555 long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT 556 if (endptr != 0) { 557 *endptr = real_endptr; 558 } 559 if (IsValidStrtolBase(base)) { 560 FixRealStrtolEndptr(nptr, &real_endptr); 561 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 562 } 563 return result; 564} 565 566INTERCEPTOR(int, atoi, const char *nptr) { 567#if SANITIZER_MAC 568 if (!asan_inited) return REAL(atoi)(nptr); 569#endif 570 ENSURE_ASAN_INITED(); 571 if (!flags()->replace_str) { 572 return REAL(atoi)(nptr); 573 } 574 char *real_endptr; 575 // "man atoi" tells that behavior of atoi(nptr) is the same as 576 // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the 577 // parsed integer can't be stored in *long* type (even if it's 578 // different from int). So, we just imitate this behavior. 579 int result = REAL(strtol)(nptr, &real_endptr, 10); 580 FixRealStrtolEndptr(nptr, &real_endptr); 581 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 582 return result; 583} 584 585INTERCEPTOR(long, atol, const char *nptr) { // NOLINT 586#if SANITIZER_MAC 587 if (!asan_inited) return REAL(atol)(nptr); 588#endif 589 ENSURE_ASAN_INITED(); 590 if (!flags()->replace_str) { 591 return REAL(atol)(nptr); 592 } 593 char *real_endptr; 594 long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT 595 FixRealStrtolEndptr(nptr, &real_endptr); 596 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 597 return result; 598} 599 600#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 601INTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT 602 char **endptr, int base) { 603 ENSURE_ASAN_INITED(); 604 if (!flags()->replace_str) { 605 return REAL(strtoll)(nptr, endptr, base); 606 } 607 char *real_endptr; 608 long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT 609 if (endptr != 0) { 610 *endptr = real_endptr; 611 } 612 // If base has unsupported value, strtoll can exit with EINVAL 613 // without reading any characters. So do additional checks only 614 // if base is valid. 615 if (IsValidStrtolBase(base)) { 616 FixRealStrtolEndptr(nptr, &real_endptr); 617 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 618 } 619 return result; 620} 621 622INTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT 623 ENSURE_ASAN_INITED(); 624 if (!flags()->replace_str) { 625 return REAL(atoll)(nptr); 626 } 627 char *real_endptr; 628 long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT 629 FixRealStrtolEndptr(nptr, &real_endptr); 630 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 631 return result; 632} 633#endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL 634 635static void AtCxaAtexit(void *unused) { 636 (void)unused; 637 StopInitOrderChecking(); 638} 639 640#if ASAN_INTERCEPT___CXA_ATEXIT 641INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, 642 void *dso_handle) { 643 ENSURE_ASAN_INITED(); 644 int res = REAL(__cxa_atexit)(func, arg, dso_handle); 645 REAL(__cxa_atexit)(AtCxaAtexit, 0, 0); 646 return res; 647} 648#endif // ASAN_INTERCEPT___CXA_ATEXIT 649 650#if !SANITIZER_MAC 651#define ASAN_INTERCEPT_FUNC(name) do { \ 652 if (!INTERCEPT_FUNCTION(name) && flags()->verbosity > 0) \ 653 Report("AddressSanitizer: failed to intercept '" #name "'\n"); \ 654 } while (0) 655#else 656// OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION. 657#define ASAN_INTERCEPT_FUNC(name) 658#endif // SANITIZER_MAC 659 660#if SANITIZER_WINDOWS 661INTERCEPTOR_WINAPI(DWORD, CreateThread, 662 void* security, uptr stack_size, 663 DWORD (__stdcall *start_routine)(void*), void* arg, 664 DWORD thr_flags, void* tid) { 665 // Strict init-order checking in thread-hostile. 666 if (flags()->strict_init_order) 667 StopInitOrderChecking(); 668 GET_STACK_TRACE_THREAD; 669 u32 current_tid = GetCurrentTidOrInvalid(); 670 AsanThread *t = AsanThread::Create(start_routine, arg); 671 CreateThreadContextArgs args = { t, &stack }; 672 bool detached = false; // FIXME: how can we determine it on Windows? 673 asanThreadRegistry().CreateThread(*(uptr*)t, detached, current_tid, &args); 674 return REAL(CreateThread)(security, stack_size, 675 asan_thread_start, t, thr_flags, tid); 676} 677 678namespace __asan { 679void InitializeWindowsInterceptors() { 680 ASAN_INTERCEPT_FUNC(CreateThread); 681} 682 683} // namespace __asan 684#endif 685 686// ---------------------- InitializeAsanInterceptors ---------------- {{{1 687namespace __asan { 688void InitializeAsanInterceptors() { 689 static bool was_called_once; 690 CHECK(was_called_once == false); 691 was_called_once = true; 692 SANITIZER_COMMON_INTERCEPTORS_INIT; 693 694 // Intercept mem* functions. 695 ASAN_INTERCEPT_FUNC(memcmp); 696 ASAN_INTERCEPT_FUNC(memmove); 697 ASAN_INTERCEPT_FUNC(memset); 698 if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { 699 ASAN_INTERCEPT_FUNC(memcpy); 700 } 701 702 // Intercept str* functions. 703 ASAN_INTERCEPT_FUNC(strcat); // NOLINT 704 ASAN_INTERCEPT_FUNC(strchr); 705 ASAN_INTERCEPT_FUNC(strcmp); 706 ASAN_INTERCEPT_FUNC(strcpy); // NOLINT 707 ASAN_INTERCEPT_FUNC(strlen); 708 ASAN_INTERCEPT_FUNC(strncat); 709 ASAN_INTERCEPT_FUNC(strncmp); 710 ASAN_INTERCEPT_FUNC(strncpy); 711#if ASAN_INTERCEPT_STRDUP 712 ASAN_INTERCEPT_FUNC(strdup); 713#endif 714#if ASAN_INTERCEPT_STRNLEN 715 ASAN_INTERCEPT_FUNC(strnlen); 716#endif 717#if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 718 ASAN_INTERCEPT_FUNC(index); 719#endif 720 721 ASAN_INTERCEPT_FUNC(atoi); 722 ASAN_INTERCEPT_FUNC(atol); 723 ASAN_INTERCEPT_FUNC(strtol); 724#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 725 ASAN_INTERCEPT_FUNC(atoll); 726 ASAN_INTERCEPT_FUNC(strtoll); 727#endif 728 729#if ASAN_INTERCEPT_MLOCKX 730 // Intercept mlock/munlock. 731 ASAN_INTERCEPT_FUNC(mlock); 732 ASAN_INTERCEPT_FUNC(munlock); 733 ASAN_INTERCEPT_FUNC(mlockall); 734 ASAN_INTERCEPT_FUNC(munlockall); 735#endif 736 737 // Intecept signal- and jump-related functions. 738 ASAN_INTERCEPT_FUNC(longjmp); 739#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 740 ASAN_INTERCEPT_FUNC(sigaction); 741 ASAN_INTERCEPT_FUNC(signal); 742#endif 743#if ASAN_INTERCEPT_SWAPCONTEXT 744 ASAN_INTERCEPT_FUNC(swapcontext); 745#endif 746#if ASAN_INTERCEPT__LONGJMP 747 ASAN_INTERCEPT_FUNC(_longjmp); 748#endif 749#if ASAN_INTERCEPT_SIGLONGJMP 750 ASAN_INTERCEPT_FUNC(siglongjmp); 751#endif 752 753 // Intercept exception handling functions. 754#if ASAN_INTERCEPT___CXA_THROW 755 INTERCEPT_FUNCTION(__cxa_throw); 756#endif 757 758 // Intercept threading-related functions 759#if ASAN_INTERCEPT_PTHREAD_CREATE 760 ASAN_INTERCEPT_FUNC(pthread_create); 761#endif 762 763 // Intercept atexit function. 764#if ASAN_INTERCEPT___CXA_ATEXIT 765 ASAN_INTERCEPT_FUNC(__cxa_atexit); 766#endif 767 768 // Some Windows-specific interceptors. 769#if SANITIZER_WINDOWS 770 InitializeWindowsInterceptors(); 771#endif 772 773 if (flags()->verbosity > 0) { 774 Report("AddressSanitizer: libc interceptors initialized\n"); 775 } 776} 777 778} // namespace __asan 779