asan_interceptors.cc revision d47189c1b63a4de755d7ec071f8d56c8d01cc667
11e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===-- asan_interceptors.cc ------------------------------------*- C++ -*-===// 21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The LLVM Compiler Infrastructure 41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source 61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details. 71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 12d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// Intercept various libc functions. 131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_interceptors.h" 151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_allocator.h" 171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_interface.h" 181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h" 19547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#include "asan_mac.h" 201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_mapping.h" 211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stack.h" 221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stats.h" 234803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#include "asan_thread_registry.h" 241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 254803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#include <new> 26af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany#include <ctype.h> 271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <dlfcn.h> 281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2935dd9d8f54f15f16be6c224e303bbf75d667f248Kostya Serebryany#include <string.h> 3035dd9d8f54f15f16be6c224e303bbf75d667f248Kostya Serebryany#include <strings.h> 312fc648c5d1775f13844d4459347e2b7328411e85Kostya Serebryany#include <pthread.h> 3235dd9d8f54f15f16be6c224e303bbf75d667f248Kostya Serebryany 33d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// To replace weak system functions on Linux we just need to declare functions 34d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// with same names in our library and then obtain the real function pointers 35d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// using dlsym(). This is not so on Mac OS, where the two-level namespace makes 36d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// our replacement functions invisible to other libraries. This may be overcomed 37d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// using the DYLD_FORCE_FLAT_NAMESPACE, but some errors loading the shared 38d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// libraries in Chromium were noticed when doing so. 39d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// Instead we use mach_override, a handy framework for patching functions at 40d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// runtime. To avoid possible name clashes, our replacement functions have 41d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// the "wrap_" prefix on Mac. 42d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// 43d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// After interception, the calls to system functions will be substituted by 44d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// calls to our interceptors. We store pointers to system function f() 45d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// in __asan::real_f(). 46d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// 47d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// TODO(glider): mach_override_ptr() tends to spend too much time 48d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// in allocateBranchIsland(). This should be ok for real-word 49d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// application, but slows down our tests which fork too many children. 50d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#ifdef __APPLE__ 51d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#include "mach_override/mach_override.h" 52d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define WRAPPER_NAME(x) "wrap_"#x 53d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany 54d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define OVERRIDE_FUNCTION(oldfunc, newfunc) \ 55d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany CHECK(0 == __asan_mach_override_ptr((void*)(oldfunc), \ 56d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany (void*)(newfunc), \ 57d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany (void**)&real_##oldfunc)); \ 58d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany CHECK(real_##oldfunc != NULL); 59d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany 60d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define OVERRIDE_FUNCTION_IF_EXISTS(oldfunc, newfunc) \ 61d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany do { __asan_mach_override_ptr((void*)(oldfunc), \ 62d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany (void*)(newfunc), \ 63d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany (void**)&real_##oldfunc); } while (0) 64d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany 65d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define INTERCEPT_FUNCTION(func) \ 66d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany OVERRIDE_FUNCTION(func, WRAP(func)) 67d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany 68d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define INTERCEPT_FUNCTION_IF_EXISTS(func) \ 69d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany OVERRIDE_FUNCTION_IF_EXISTS(func, WRAP(func)) 70d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany 71d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#else // __linux__ 72d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define WRAPPER_NAME(x) #x 73d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany 74d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define INTERCEPT_FUNCTION(func) \ 75d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany CHECK((real_##func = (func##_f)dlsym(RTLD_NEXT, #func))); 76d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany 77d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#define INTERCEPT_FUNCTION_IF_EXISTS(func) \ 78d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany do { real_##func = (func##_f)dlsym(RTLD_NEXT, #func); } while (0) 79d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany#endif 80d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany 811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan { 821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 834803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanytypedef void (*longjmp_f)(void *env, int val); 844803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanytypedef longjmp_f _longjmp_f; 854803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanytypedef longjmp_f siglongjmp_f; 864803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanytypedef void (*__cxa_throw_f)(void *, void *, void *); 87d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryanytypedef int (*pthread_create_f)(void *thread, const void *attr, 884803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany void *(*start_routine) (void *), void *arg); 894803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#ifdef __APPLE__ 904803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanydispatch_async_f_f real_dispatch_async_f; 914803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanydispatch_sync_f_f real_dispatch_sync_f; 924803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanydispatch_after_f_f real_dispatch_after_f; 934803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanydispatch_barrier_async_f_f real_dispatch_barrier_async_f; 944803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanydispatch_group_async_f_f real_dispatch_group_async_f; 954803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanypthread_workqueue_additem_np_f real_pthread_workqueue_additem_np; 964803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#endif 974803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 984803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanysigaction_f real_sigaction; 994803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanysignal_f real_signal; 1004803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanylongjmp_f real_longjmp; 1014803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany_longjmp_f real__longjmp; 1024803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanysiglongjmp_f real_siglongjmp; 1034803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany__cxa_throw_f real___cxa_throw; 1044803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanypthread_create_f real_pthread_create; 1054803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 1061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyindex_f real_index; 10752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanymemcmp_f real_memcmp; 1081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanymemcpy_f real_memcpy; 1091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanymemmove_f real_memmove; 1101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanymemset_f real_memset; 111af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryanystrcasecmp_f real_strcasecmp; 1120985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryanystrcat_f real_strcat; 1131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrchr_f real_strchr; 1141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrcmp_f real_strcmp; 1151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrcpy_f real_strcpy; 1161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrdup_f real_strdup; 1171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrlen_f real_strlen; 118af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryanystrncasecmp_f real_strncasecmp; 1191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrncmp_f real_strncmp; 1201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrncpy_f real_strncpy; 1211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystrnlen_f real_strnlen; 1221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Instruments read/write access to a single byte in memory. 1241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// On error calls __asan_report_error, which aborts the program. 1251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany__attribute__((noinline)) 1261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystatic void AccessAddress(uintptr_t address, bool isWrite) { 1271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (__asan_address_is_poisoned((void*)address)) { 1281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_BP_PC_SP; 1291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany __asan_report_error(pc, bp, sp, address, isWrite, /* access_size */ 1); 1301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 1311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE, 1341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// and ASAN_WRITE_RANGE as macro instead of function so 1351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// that no extra frames are created, and stack trace contains 1361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// relevant information only. 1371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Instruments read/write access to a memory range. 1391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// More complex implementation is possible, for now just 1401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// checking the first and the last byte of a range. 1411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \ 1421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (size > 0) { \ 1431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany uintptr_t ptr = (uintptr_t)(offset); \ 1441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany AccessAddress(ptr, isWrite); \ 1451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany AccessAddress(ptr + (size) - 1, isWrite); \ 1461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } \ 147e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 1481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_READ_RANGE(offset, size) do { \ 1501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ACCESS_MEMORY_RANGE(offset, size, false); \ 151e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 1521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_WRITE_RANGE(offset, size) do { \ 1541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ACCESS_MEMORY_RANGE(offset, size, true); \ 155e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 1561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Behavior of functions like "memcpy" or "strcpy" is undefined 1581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// if memory intervals overlap. We report error in this case. 1591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Macro is used to avoid creation of new frames. 1600985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryanystatic inline bool RangesOverlap(const char *offset1, size_t length1, 1610985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany const char *offset2, size_t length2) { 1620985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1)); 1631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 164c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \ 1651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany const char *offset1 = (const char*)_offset1; \ 1661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany const char *offset2 = (const char*)_offset2; \ 1670985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany if (RangesOverlap(offset1, length1, offset2, length2)) { \ 168c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany Report("ERROR: AddressSanitizer %s-param-overlap: " \ 1691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany "memory ranges [%p,%p) and [%p, %p) overlap\n", \ 170c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany name, offset1, offset1 + length1, offset2, offset2 + length2); \ 1711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany PRINT_CURRENT_STACK(); \ 1721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ShowStatsAndAbort(); \ 1731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } \ 174e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 1751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 176e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany#define ENSURE_ASAN_INITED() do { \ 177e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany CHECK(!asan_init_is_running); \ 178e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany if (!asan_inited) { \ 179e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany __asan_init(); \ 180e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany } \ 181e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 1821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanysize_t internal_strlen(const char *s) { 1841e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany size_t i = 0; 1851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany while (s[i]) i++; 1861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return i; 1871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanysize_t internal_strnlen(const char *s, size_t maxlen) { 1901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (real_strnlen != NULL) { 1911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_strnlen(s, maxlen); 1921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 1931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany size_t i = 0; 1941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany while (i < maxlen && s[i]) i++; 1951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return i; 1961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 198de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyvoid* internal_memchr(const void* s, int c, size_t n) { 199de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany const char* t = (char*)s; 200de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany for (size_t i = 0; i < n; ++i, ++t) 201de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany if (*t == c) 202de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany return (void*)t; 203de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany return NULL; 204de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany} 205de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany 206de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyint internal_memcmp(const void* s1, const void* s2, size_t n) { 207de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany const char* t1 = (char*)s1; 208de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany const char* t2 = (char*)s2; 209de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany for (size_t i = 0; i < n; ++i, ++t1, ++t2) 210de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany if (*t1 != *t2) 211de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany return *t1 < *t2 ? -1 : 1; 212de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany return 0; 213de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany} 214de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany 215a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryanychar *internal_strstr(const char *haystack, const char *needle) { 216a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany // This is O(N^2), but we are not using it in hot places. 217a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany size_t len1 = internal_strlen(haystack); 218a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany size_t len2 = internal_strlen(needle); 219a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany if (len1 < len2) return 0; 220a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany for (size_t pos = 0; pos <= len1 - len2; pos++) { 221a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany if (internal_memcmp(haystack + pos, needle, len2) == 0) 222a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany return (char*)haystack + pos; 223a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany } 224a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany return 0; 225a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany} 226a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany 227a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryanychar *internal_strncat(char *dst, const char *src, size_t n) { 228a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany size_t len = internal_strlen(dst); 229a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany size_t i; 230a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany for (i = 0; i < n && src[i]; i++) 231a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany dst[len + i] = src[i]; 232a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany dst[len + i] = 0; 233a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany return dst; 234a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany} 2351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // namespace __asan 2371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// ---------------------- Wrappers ---------------- {{{1 2391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyusing namespace __asan; // NOLINT 2401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2414803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#define OPERATOR_NEW_BODY \ 2424803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany GET_STACK_TRACE_HERE_FOR_MALLOC;\ 2434803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return asan_memalign(0, size, &stack); 2444803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 2454803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#ifdef ANDROID 2464803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid *operator new(size_t size) { OPERATOR_NEW_BODY; } 2474803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid *operator new[](size_t size) { OPERATOR_NEW_BODY; } 2484803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#else 2494803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid *operator new(size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; } 2504803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid *operator new[](size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; } 2514803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid *operator new(size_t size, std::nothrow_t const&) throw() 2524803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany{ OPERATOR_NEW_BODY; } 2534803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid *operator new[](size_t size, std::nothrow_t const&) throw() 2544803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany{ OPERATOR_NEW_BODY; } 2554803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#endif 2564803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 2574803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#define OPERATOR_DELETE_BODY \ 2584803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany GET_STACK_TRACE_HERE_FOR_FREE(ptr);\ 2594803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany asan_free(ptr, &stack); 2604803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 2614803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid operator delete(void *ptr) throw() { OPERATOR_DELETE_BODY; } 2624803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid operator delete[](void *ptr) throw() { OPERATOR_DELETE_BODY; } 2634803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid operator delete(void *ptr, std::nothrow_t const&) throw() 2644803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany{ OPERATOR_DELETE_BODY; } 2654803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid operator delete[](void *ptr, std::nothrow_t const&) throw() 2664803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany{ OPERATOR_DELETE_BODY;} 2674803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 2684803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanystatic void *asan_thread_start(void *arg) { 2694803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany AsanThread *t = (AsanThread*)arg; 2704803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany asanThreadRegistry().SetCurrent(t); 2714803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return t->ThreadStart(); 2724803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 2734803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 2744803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" 2754803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#ifndef __APPLE__ 2764803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany__attribute__((visibility("default"))) 2774803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#endif 2782fc648c5d1775f13844d4459347e2b7328411e85Kostya Serebryanyint WRAP(pthread_create)(pthread_t *thread, const pthread_attr_t *attr, 2794803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany void *(*start_routine) (void *), void *arg) { 2804803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); 2814803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); 2824803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany AsanThread *t = AsanThread::Create(current_tid, start_routine, arg); 2834803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany asanThreadRegistry().RegisterThread(t, current_tid, &stack); 2844803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return real_pthread_create(thread, attr, asan_thread_start, t); 2854803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 2864803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 2874803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" 2884803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyvoid *WRAP(signal)(int signum, void *handler) { 2894803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany if (!AsanInterceptsSignal(signum)) { 2904803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return real_signal(signum, handler); 2914803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany } 2924803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return NULL; 2934803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 2944803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 2954803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" 29673248e304bfa86596c667b30feda0bf3c61f6ac9Kostya Serebryanyextern int (sigaction)(int signum, const void *act, void *oldact); 29773248e304bfa86596c667b30feda0bf3c61f6ac9Kostya Serebryany 29873248e304bfa86596c667b30feda0bf3c61f6ac9Kostya Serebryanyextern "C" 299547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanyint WRAP(sigaction)(int signum, const void *act, void *oldact) { 3004803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany if (!AsanInterceptsSignal(signum)) { 3014803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return real_sigaction(signum, act, oldact); 3024803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany } 3034803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return 0; 3044803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3054803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 3064803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 3074803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanystatic void UnpoisonStackFromHereToTop() { 3084803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany int local_stack; 3094803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany AsanThread *curr_thread = asanThreadRegistry().GetCurrent(); 3104803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany CHECK(curr_thread); 3114803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany uintptr_t top = curr_thread->stack_top(); 3124803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany uintptr_t bottom = ((uintptr_t)&local_stack - kPageSize) & ~(kPageSize-1); 3134803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany PoisonShadow(bottom, top - bottom, 0); 3144803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3154803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 3164803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" void WRAP(longjmp)(void *env, int val) { 3174803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany UnpoisonStackFromHereToTop(); 3184803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany real_longjmp(env, val); 3194803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3204803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 3214803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" void WRAP(_longjmp)(void *env, int val) { 3224803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany UnpoisonStackFromHereToTop(); 3234803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany real__longjmp(env, val); 3244803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3254803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 3264803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" void WRAP(siglongjmp)(void *env, int val) { 3274803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany UnpoisonStackFromHereToTop(); 3284803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany real_siglongjmp(env, val); 3294803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3304803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 3314803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" void __cxa_throw(void *a, void *b, void *c); 3324803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 3334803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#if ASAN_HAS_EXCEPTIONS == 1 3344803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" void WRAP(__cxa_throw)(void *a, void *b, void *c) { 3354803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany CHECK(&real___cxa_throw); 3364803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany UnpoisonStackFromHereToTop(); 3374803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany real___cxa_throw(a, b, c); 3384803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3394803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#endif 3404803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 3414803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" { 3424803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// intercept mlock and friends. 3434803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// Since asan maps 16T of RAM, mlock is completely unfriendly to asan. 3444803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// All functions return 0 (success). 3454803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanystatic void MlockIsUnsupported() { 3464803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany static bool printed = 0; 3474803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany if (printed) return; 3484803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany printed = true; 3494803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n"); 3504803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3514803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint mlock(const void *addr, size_t len) { 3524803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany MlockIsUnsupported(); 3534803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return 0; 3544803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3554803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint munlock(const void *addr, size_t len) { 3564803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany MlockIsUnsupported(); 3574803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return 0; 3584803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3594803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint mlockall(int flags) { 3604803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany MlockIsUnsupported(); 3614803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return 0; 3624803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3634803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint munlockall(void) { 3644803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany MlockIsUnsupported(); 3654803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return 0; 3664803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3674803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} // extern "C" 3684803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 3694803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 3704803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 37152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanystatic inline int CharCmp(unsigned char c1, unsigned char c2) { 37252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 37352fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany} 37452fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany 37552fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanystatic inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 37652fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany int c1_low = tolower(c1); 37752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany int c2_low = tolower(c2); 37852fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany return c1_low - c2_low; 37952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany} 38052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany 38120688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 38252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanyint WRAP(memcmp)(const void *a1, const void *a2, size_t size) { 38352fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany ENSURE_ASAN_INITED(); 38452fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany unsigned char c1 = 0, c2 = 0; 38552fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany const unsigned char *s1 = (const unsigned char*)a1; 38652fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany const unsigned char *s2 = (const unsigned char*)a2; 38752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany size_t i; 38852fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany for (i = 0; i < size; i++) { 38952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany c1 = s1[i]; 39052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany c2 = s2[i]; 39152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany if (c1 != c2) break; 39252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany } 39352fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany ASAN_READ_RANGE(s1, Min(i + 1, size)); 39452fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany ASAN_READ_RANGE(s2, Min(i + 1, size)); 39552fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany return CharCmp(c1, c2); 39652fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany} 39752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany 39820688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 3991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *WRAP(memcpy)(void *to, const void *from, size_t size) { 4001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // memcpy is called during __asan_init() from the internals 4011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // of printf(...). 4021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 4031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_memcpy(to, from, size); 4041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 405e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 4061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_intrin) { 407c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); 4081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(from, size); 4091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(to, size); 4101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 4111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_memcpy(to, from, size); 4121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 41420688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 4151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *WRAP(memmove)(void *to, const void *from, size_t size) { 416e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 4171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_intrin) { 4181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(from, size); 4191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(to, size); 4201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 4211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_memmove(to, from, size); 4221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 42420688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 4251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *WRAP(memset)(void *block, int c, size_t size) { 426e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany // memset is called inside INTERCEPT_FUNCTION on Mac. 427e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany if (asan_init_is_running) { 428e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany return real_memset(block, c, size); 429e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany } 430e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 4311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_intrin) { 4321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(block, size); 4331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 4341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_memset(block, c, size); 4351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 4371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#ifndef __APPLE__ 43820688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 4391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanychar *WRAP(index)(const char *str, int c) 4401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany __attribute__((alias(WRAPPER_NAME(strchr)))); 4411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#endif 4421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 44320688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 4441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanychar *WRAP(strchr)(const char *str, int c) { 445e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 4461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany char *result = real_strchr(str, c); 4471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_str) { 4481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany size_t bytes_read = (result ? result - str : real_strlen(str)) + 1; 4491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(str, bytes_read); 4501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 4511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return result; 4521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 45420688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 455af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryanyint WRAP(strcasecmp)(const char *s1, const char *s2) { 456af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany ENSURE_ASAN_INITED(); 457af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany unsigned char c1, c2; 458af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany size_t i; 459af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany for (i = 0; ; i++) { 460af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany c1 = (unsigned char)s1[i]; 461af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany c2 = (unsigned char)s2[i]; 462af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 463af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany } 464af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany ASAN_READ_RANGE(s1, i + 1); 465af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany ASAN_READ_RANGE(s2, i + 1); 466af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany return CharCaseCmp(c1, c2); 467af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany} 468af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany 46920688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 4700985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryanychar *WRAP(strcat)(char *to, const char *from) { // NOLINT 4710985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany ENSURE_ASAN_INITED(); 4720985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany if (FLAG_replace_str) { 4730985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany size_t from_length = real_strlen(from); 4740985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany ASAN_READ_RANGE(from, from_length + 1); 4750985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany if (from_length > 0) { 4760985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany size_t to_length = real_strlen(to); 4770985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany ASAN_READ_RANGE(to, to_length); 4780985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany ASAN_WRITE_RANGE(to + to_length, from_length + 1); 479c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany CHECK_RANGES_OVERLAP("strcat", to, to_length + 1, from, from_length + 1); 4800985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany } 4810985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany } 4820985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany return real_strcat(to, from); 4830985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany} 4840985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany 48520688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 4861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyint WRAP(strcmp)(const char *s1, const char *s2) { 4871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strcmp is called from malloc_default_purgeable_zone() 4881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 4891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 4901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_strcmp(s1, s2); 4911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 4921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany unsigned char c1, c2; 4931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany size_t i; 4941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany for (i = 0; ; i++) { 4951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c1 = (unsigned char)s1[i]; 4961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c2 = (unsigned char)s2[i]; 4971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (c1 != c2 || c1 == '\0') break; 4981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 4991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s1, i + 1); 5001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s2, i + 1); 5011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return CharCmp(c1, c2); 5021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 5031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 50420688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 5051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanychar *WRAP(strcpy)(char *to, const char *from) { // NOLINT 5061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strcpy is called from malloc_default_purgeable_zone() 5071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 5081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 5091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_strcpy(to, from); 5101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 511e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 5121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_str) { 5131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany size_t from_size = real_strlen(from) + 1; 514c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size); 5151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(from, from_size); 5161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(to, from_size); 5171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 5181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_strcpy(to, from); 5191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 5201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 52120688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 5221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanychar *WRAP(strdup)(const char *s) { 523e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 5241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_str) { 5251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany size_t length = real_strlen(s); 5261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s, length + 1); 5271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 5281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_strdup(s); 5291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 5301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 53120688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 5321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanysize_t WRAP(strlen)(const char *s) { 5331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strlen is called from malloc_default_purgeable_zone() 5341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 5351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 5361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_strlen(s); 5371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 538e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 5391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany size_t length = real_strlen(s); 5401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_str) { 5411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s, length + 1); 5421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 5431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return length; 5441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 5451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 54620688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 547af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryanyint WRAP(strncasecmp)(const char *s1, const char *s2, size_t size) { 548af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany ENSURE_ASAN_INITED(); 549af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany unsigned char c1 = 0, c2 = 0; 550af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany size_t i; 551af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany for (i = 0; i < size; i++) { 552af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany c1 = (unsigned char)s1[i]; 553af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany c2 = (unsigned char)s2[i]; 554af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 555af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany } 556af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany ASAN_READ_RANGE(s1, Min(i + 1, size)); 557af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany ASAN_READ_RANGE(s2, Min(i + 1, size)); 558af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany return CharCaseCmp(c1, c2); 559af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany} 560af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany 56120688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 5621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyint WRAP(strncmp)(const char *s1, const char *s2, size_t size) { 5631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strncmp is called from malloc_default_purgeable_zone() 5641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 5651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 5661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_strncmp(s1, s2, size); 5671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 5681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany unsigned char c1 = 0, c2 = 0; 5691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany size_t i; 5701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany for (i = 0; i < size; i++) { 5711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c1 = (unsigned char)s1[i]; 5721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c2 = (unsigned char)s2[i]; 5731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (c1 != c2 || c1 == '\0') break; 5741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 5752d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany ASAN_READ_RANGE(s1, Min(i + 1, size)); 5762d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany ASAN_READ_RANGE(s2, Min(i + 1, size)); 5771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return CharCmp(c1, c2); 5781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 5791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 58020688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 5811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanychar *WRAP(strncpy)(char *to, const char *from, size_t size) { 582e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 5831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_str) { 5842d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany size_t from_size = Min(size, internal_strnlen(from, size) + 1); 585c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size); 5861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(from, from_size); 5871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(to, size); 5881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 5891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_strncpy(to, from, size); 5901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 5911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 5921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#ifndef __APPLE__ 59320688eb9b1099963170fe8c440cb910d9b2df40bKostya Serebryanyextern "C" 5941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanysize_t WRAP(strnlen)(const char *s, size_t maxlen) { 595e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 5961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany size_t length = real_strnlen(s, maxlen); 5971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_str) { 5982d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany ASAN_READ_RANGE(s, Min(length + 1, maxlen)); 5991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 6001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return length; 6011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 602d66a8d8f56c66c9749b6d75c61870a121d4d9307Kostya Serebryany#endif 603547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 604547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany// ---------------------- InitializeAsanInterceptors ---------------- {{{1 605547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanynamespace __asan { 606547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanyvoid InitializeAsanInterceptors() { 607547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#ifndef __APPLE__ 608547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(index); 609547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#else 610547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany OVERRIDE_FUNCTION(index, WRAP(strchr)); 611547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#endif 612547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(memcmp); 613547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(memcpy); 614547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(memmove); 615547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(memset); 616547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(strcasecmp); 617547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(strcat); // NOLINT 618547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(strchr); 619547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(strcmp); 620547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(strcpy); // NOLINT 621547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(strdup); 622547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(strlen); 623547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(strncasecmp); 624547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(strncmp); 625547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(strncpy); 626547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 627547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(sigaction); 628547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(signal); 629547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(longjmp); 630547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(_longjmp); 631547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION_IF_EXISTS(__cxa_throw); 632547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(pthread_create); 633547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 634547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#ifdef __APPLE__ 635547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(dispatch_async_f); 636547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(dispatch_sync_f); 637547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(dispatch_after_f); 638547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(dispatch_barrier_async_f); 639547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(dispatch_group_async_f); 640547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany // We don't need to intercept pthread_workqueue_additem_np() to support the 641547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany // libdispatch API, but it helps us to debug the unsupported functions. Let's 642547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany // intercept it only during verbose runs. 643547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany if (FLAG_v >= 2) { 644547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(pthread_workqueue_additem_np); 645547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany } 646547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#else 647547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it 648547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany // there. 649547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(siglongjmp); 650547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#endif 651547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 652547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#ifndef __APPLE__ 653547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany INTERCEPT_FUNCTION(strnlen); 654547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#endif 655547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany if (FLAG_v > 0) { 656547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany Printf("AddressSanitizer: libc interceptors initialized\n"); 657547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany } 658547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany} 659547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 660547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany} // namespace __asan 661