asan_interceptors.cc revision beda44f87166f91dbeef3d174d77395653bead4d
1e5f5895bda30f374b0b51412fd4d837fa59aed66Alexey Samsonov//===-- asan_interceptors.cc ----------------------------------------------===// 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" 1705bf9a51dfeac0f84f6dbc2dacf987249c0fc612Alexander Potapenko#include "asan_intercepted_functions.h" 181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_interface.h" 191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h" 201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_mapping.h" 21487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov#include "asan_report.h" 221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stack.h" 231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stats.h" 244803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#include "asan_thread_registry.h" 255b29018cf422e7711fb760b733c32127397a43fcAlexey Samsonov#include "interception/interception.h" 26c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov#include "sanitizer_common/sanitizer_libc.h" 27c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov 281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan { 291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Instruments read/write access to a single byte in memory. 311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// On error calls __asan_report_error, which aborts the program. 329f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany#define ACCESS_ADDRESS(address, isWrite) do { \ 3379d12e87fbcc1b2342d76367b99b83adf9cbf499Alexander Potapenko if (!AddrIsInMem(address) || AddressIsPoisoned(address)) { \ 349f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany GET_CURRENT_PC_BP_SP; \ 359f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany __asan_report_error(pc, bp, sp, address, isWrite, /* access_size */ 1); \ 369f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany } \ 379f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany} while (0) 381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE, 401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// and ASAN_WRITE_RANGE as macro instead of function so 411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// that no extra frames are created, and stack trace contains 421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// relevant information only. 431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Instruments read/write access to a memory range. 451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// More complex implementation is possible, for now just 461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// checking the first and the last byte of a range. 471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \ 481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (size > 0) { \ 493f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr ptr = (uptr)(offset); \ 509f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany ACCESS_ADDRESS(ptr, isWrite); \ 519f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany ACCESS_ADDRESS(ptr + (size) - 1, isWrite); \ 521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } \ 53e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_READ_RANGE(offset, size) do { \ 561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ACCESS_MEMORY_RANGE(offset, size, false); \ 57e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_WRITE_RANGE(offset, size) do { \ 601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ACCESS_MEMORY_RANGE(offset, size, true); \ 61e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Behavior of functions like "memcpy" or "strcpy" is undefined 641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// if memory intervals overlap. We report error in this case. 651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Macro is used to avoid creation of new frames. 663f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanystatic inline bool RangesOverlap(const char *offset1, uptr length1, 673f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany const char *offset2, uptr length2) { 680985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1)); 691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 70c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \ 711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany const char *offset1 = (const char*)_offset1; \ 721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany const char *offset2 = (const char*)_offset2; \ 730985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany if (RangesOverlap(offset1, length1, offset2, length2)) { \ 74487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov GET_STACK_TRACE_HERE(kStackTraceMax); \ 75487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \ 76487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov offset2, length2, &stack); \ 771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } \ 78e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 80e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany#define ENSURE_ASAN_INITED() do { \ 81e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany CHECK(!asan_init_is_running); \ 82e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany if (!asan_inited) { \ 83e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany __asan_init(); \ 84e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany } \ 85e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 87c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovstatic inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) { 8881a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#if ASAN_INTERCEPT_STRNLEN 893f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany if (REAL(strnlen) != 0) { 9009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strnlen)(s, maxlen); 911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 92f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov#endif 93c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov return internal_strnlen(s, maxlen); 94a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany} 951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // namespace __asan 971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// ---------------------- Wrappers ---------------- {{{1 991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyusing namespace __asan; // NOLINT 1001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 101600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanovstatic thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { 1024803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany AsanThread *t = (AsanThread*)arg; 1034803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany asanThreadRegistry().SetCurrent(t); 1044803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return t->ThreadStart(); 1054803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 1064803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 107fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_PTHREAD_CREATE 108b8ef925563f8dde5be837c4b0569082867c5f14cEvgeniy StepanovINTERCEPTOR(int, pthread_create, void *thread, 109b8ef925563f8dde5be837c4b0569082867c5f14cEvgeniy Stepanov void *attr, void *(*start_routine)(void*), void *arg) { 1109cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov GET_STACK_TRACE_HERE(kStackTraceMax); 111e0cff0bc20ae51790c8edfbceb817e18ebf5355eKostya Serebryany u32 current_tid = asanThreadRegistry().GetCurrentTidOrInvalid(); 11255cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack); 11355cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov asanThreadRegistry().RegisterThread(t); 11409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(pthread_create)(thread, attr, asan_thread_start, t); 1154803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 116fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif // ASAN_INTERCEPT_PTHREAD_CREATE 1174803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 11834a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 119f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void*, signal, int signum, void *handler) { 120034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko if (!AsanInterceptsSignal(signum)) { 121034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko return REAL(signal)(signum, handler); 1224803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany } 1233f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany return 0; 1244803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 1254803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 126da13ba833b046553f50b54538e4828287ddbf5c0Alexey SamsonovINTERCEPTOR(int, sigaction, int signum, const struct sigaction *act, 127da13ba833b046553f50b54538e4828287ddbf5c0Alexey Samsonov struct sigaction *oldact) { 128034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko if (!AsanInterceptsSignal(signum)) { 129034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko return REAL(sigaction)(signum, act, oldact); 1304803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany } 131034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko return 0; 1324803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 13334a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#elif ASAN_POSIX 13434a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov// We need to have defined REAL(sigaction) on posix systems. 13534a3202a2c22816a6da66959e266a2d078ded37bAlexey SamsonovDEFINE_REAL(int, sigaction, int signum, const struct sigaction *act, 13634a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov struct sigaction *oldact); 13734a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#endif // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 1384803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 139f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, longjmp, void *env, int val) { 140f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany __asan_handle_no_return(); 14109672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(longjmp)(env, val); 1424803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 1434803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 144fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT__LONGJMP 145f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, _longjmp, void *env, int val) { 146f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany __asan_handle_no_return(); 14709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(_longjmp)(env, val); 1484803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 149fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 1504803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 151fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_SIGLONGJMP 152f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, siglongjmp, void *env, int val) { 153f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany __asan_handle_no_return(); 15409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(siglongjmp)(env, val); 1554803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 15607bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif 1574803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 158fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT___CXA_THROW 159f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { 16009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov CHECK(REAL(__cxa_throw)); 161f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany __asan_handle_no_return(); 16209672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(__cxa_throw)(a, b, c); 1634803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 1644803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#endif 1654803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 1664803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// intercept mlock and friends. 1674803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// Since asan maps 16T of RAM, mlock is completely unfriendly to asan. 1684803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// All functions return 0 (success). 1694803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanystatic void MlockIsUnsupported() { 1704803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany static bool printed = 0; 1714803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany if (printed) return; 1724803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany printed = true; 1734803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n"); 1744803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 1753389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov 176f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonovextern "C" { 17700f1c091441be5c2cacb99e21bd1965a5e418242Alexander PotapenkoINTERCEPTOR(int, mlock, const void *addr, uptr len) { 1784803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany MlockIsUnsupported(); 1794803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return 0; 1804803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 1813389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov 18200f1c091441be5c2cacb99e21bd1965a5e418242Alexander PotapenkoINTERCEPTOR(int, munlock, const void *addr, uptr len) { 1834803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany MlockIsUnsupported(); 1844803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return 0; 1854803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 1863389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov 18700f1c091441be5c2cacb99e21bd1965a5e418242Alexander PotapenkoINTERCEPTOR(int, mlockall, int flags) { 1884803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany MlockIsUnsupported(); 1894803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return 0; 1904803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 1913389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov 19200f1c091441be5c2cacb99e21bd1965a5e418242Alexander PotapenkoINTERCEPTOR(int, munlockall, void) { 1934803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany MlockIsUnsupported(); 1944803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return 0; 1954803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 1964803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} // extern "C" 1974803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 19852fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanystatic inline int CharCmp(unsigned char c1, unsigned char c2) { 19952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 20052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany} 20152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany 20252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanystatic inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 2038898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov int c1_low = ToLower(c1); 2048898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov int c2_low = ToLower(c2); 20552fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany return c1_low - c2_low; 20652fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany} 20752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany 2083f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { 2090ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#if MAC_INTERPOSE_FUNCTIONS 2100ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko if (!asan_inited) return REAL(memcmp)(a1, a2, size); 2110ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#endif 21252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany ENSURE_ASAN_INITED(); 21352fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany unsigned char c1 = 0, c2 = 0; 21452fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany const unsigned char *s1 = (const unsigned char*)a1; 21552fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany const unsigned char *s2 = (const unsigned char*)a2; 2163f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr i; 21752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany for (i = 0; i < size; i++) { 21852fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany c1 = s1[i]; 21952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany c2 = s2[i]; 22052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany if (c1 != c2) break; 22152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany } 22252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany ASAN_READ_RANGE(s1, Min(i + 1, size)); 22352fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany ASAN_READ_RANGE(s2, Min(i + 1, size)); 22452fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany return CharCmp(c1, c2); 22552fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany} 22652fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany 2273f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) { 2281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // memcpy is called during __asan_init() from the internals 2291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // of printf(...). 2301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 23109672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memcpy)(to, from, size); 2321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 233e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 234cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_intrin) { 235c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany if (to != from) { 236c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany // We do not treat memcpy with to==from as a bug. 237c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany // See http://llvm.org/bugs/show_bug.cgi?id=11763. 238c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); 239c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany } 2401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(from, size); 2411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(to, size); 2421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 24309672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memcpy)(to, from, size); 2441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2463f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) { 247a1a25c1afe38e59ffb342c24bb5bb10d05679df7Alexey Samsonov if (asan_init_is_running) { 248a1a25c1afe38e59ffb342c24bb5bb10d05679df7Alexey Samsonov return REAL(memmove)(to, from, size); 249a1a25c1afe38e59ffb342c24bb5bb10d05679df7Alexey Samsonov } 250e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 251cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_intrin) { 2521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(from, size); 2531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(to, size); 2541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 25509672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memmove)(to, from, size); 2561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2583f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(void*, memset, void *block, int c, uptr size) { 259ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko // memset is called inside Printf. 260e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany if (asan_init_is_running) { 26109672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memset)(block, c, size); 262e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany } 263e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 264cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_intrin) { 2651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(block, size); 2661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 26709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memset)(block, c, size); 2681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 270f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strchr, const char *str, int c) { 2710ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#if MAC_INTERPOSE_FUNCTIONS 2720ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko if (!asan_inited) return REAL(strchr)(str, c); 2730ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#endif 274e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 27509672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov char *result = REAL(strchr)(str, c); 276cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 2773f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr bytes_read = (result ? result - str : REAL(strlen)(str)) + 1; 2781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(str, bytes_read); 2791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 2801e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return result; 2811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 283fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_INDEX 284fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov# if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 2854b0c5f240e71be4f375627e57d0f1b89600918a7Evgeniy StepanovINTERCEPTOR(char*, index, const char *string, int c) 286adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov ALIAS(WRAPPER_NAME(strchr)); 287fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov# else 288b4fefa713da3dabda1cd83ae4182c71f1683f02cAlexey SamsonovDEFINE_REAL(char*, index, const char *string, int c) 289fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov# endif 290fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif // ASAN_INTERCEPT_INDEX 291af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany 29237b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko// For both strcat() and strncat() we need to check the validity of |to| 29337b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko// argument irrespective of the |from| length. 294f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT 2950985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany ENSURE_ASAN_INITED(); 296cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 2973f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr from_length = REAL(strlen)(from); 2980985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany ASAN_READ_RANGE(from, from_length + 1); 29937b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko uptr to_length = REAL(strlen)(to); 30037b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko ASAN_READ_RANGE(to, to_length); 30137b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko ASAN_WRITE_RANGE(to + to_length, from_length + 1); 30237b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko // If the copying actually happens, the |from| string should not overlap 30337b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko // with the resulting string starting at |to|, which has a length of 30437b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko // to_length + from_length + 1. 3050985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany if (from_length > 0) { 30637b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1, 30737b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko from, from_length + 1); 3080985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany } 3090985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany } 31009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strcat)(to, from); // NOLINT 3110985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany} 3120985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany 313c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey SamsonovINTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) { 314c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov ENSURE_ASAN_INITED(); 31537b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko if (flags()->replace_str) { 316c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov uptr from_length = MaybeRealStrnlen(from, size); 31737b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko uptr copy_length = Min(size, from_length + 1); 31837b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko ASAN_READ_RANGE(from, copy_length); 319c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov uptr to_length = REAL(strlen)(to); 320c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov ASAN_READ_RANGE(to, to_length); 321c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov ASAN_WRITE_RANGE(to + to_length, from_length + 1); 322c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov if (from_length > 0) { 32337b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1, 32437b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko from, copy_length); 325c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov } 326c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov } 327c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov return REAL(strncat)(to, from, size); 328c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov} 329c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov 330f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 3310ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#if MAC_INTERPOSE_FUNCTIONS 3320ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko if (!asan_inited) return REAL(strcmp)(s1, s2); 3330ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#endif 334fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov if (asan_init_is_running) { 335fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov return REAL(strcmp)(s1, s2); 3361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 3378648e7734ff02a25706464e9e294bd217622bcaeKostya Serebryany ENSURE_ASAN_INITED(); 3381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany unsigned char c1, c2; 3393f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr i; 3401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany for (i = 0; ; i++) { 3411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c1 = (unsigned char)s1[i]; 3421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c2 = (unsigned char)s2[i]; 3431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (c1 != c2 || c1 == '\0') break; 3441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 3451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s1, i + 1); 3461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s2, i + 1); 3471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return CharCmp(c1, c2); 3481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 3491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 350f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT 3510ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#if MAC_INTERPOSE_FUNCTIONS 352beda44f87166f91dbeef3d174d77395653bead4dAlexander Potapenko if (!asan_inited) return REAL(strcpy)(to, from); // NOLINT 3530ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#endif 3541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strcpy is called from malloc_default_purgeable_zone() 3551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 3561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 35709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strcpy)(to, from); // NOLINT 3581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 359e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 360cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 3613f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr from_size = REAL(strlen)(from) + 1; 362c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size); 3631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(from, from_size); 3641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(to, from_size); 3651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 36609672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strcpy)(to, from); // NOLINT 3671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 3681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 369fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_STRDUP 370f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strdup, const char *s) { 3710ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#if MAC_INTERPOSE_FUNCTIONS 3720ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko if (!asan_inited) return REAL(strdup)(s); 3730ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#endif 374e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 375cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 3763f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr length = REAL(strlen)(s); 3771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s, length + 1); 3781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 37909672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strdup)(s); 3801e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 381fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 3821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3833f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(uptr, strlen, const char *s) { 3840ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#if MAC_INTERPOSE_FUNCTIONS 3850ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko if (!asan_inited) return REAL(strlen)(s); 3860ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#endif 3871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strlen is called from malloc_default_purgeable_zone() 3881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 3891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 39009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strlen)(s); 3911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 392e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 3933f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr length = REAL(strlen)(s); 394cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 3951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s, length + 1); 3961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 3971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return length; 3981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 3991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 400fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_STRCASECMP_AND_STRNCASECMP 401fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey SamsonovINTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 402fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov ENSURE_ASAN_INITED(); 403fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov unsigned char c1, c2; 404fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov uptr i; 405fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov for (i = 0; ; i++) { 406fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov c1 = (unsigned char)s1[i]; 407fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov c2 = (unsigned char)s2[i]; 408fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 409fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov } 410fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov ASAN_READ_RANGE(s1, i + 1); 411fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov ASAN_READ_RANGE(s2, i + 1); 412fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov return CharCaseCmp(c1, c2); 413fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov} 414fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov 4153f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, uptr n) { 416af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany ENSURE_ASAN_INITED(); 417af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany unsigned char c1 = 0, c2 = 0; 4183f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr i; 419f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov for (i = 0; i < n; i++) { 420af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany c1 = (unsigned char)s1[i]; 421af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany c2 = (unsigned char)s2[i]; 422af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 423af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany } 424f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov ASAN_READ_RANGE(s1, Min(i + 1, n)); 425f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov ASAN_READ_RANGE(s2, Min(i + 1, n)); 426af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany return CharCaseCmp(c1, c2); 427af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany} 428fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif // ASAN_INTERCEPT_STRCASECMP_AND_STRNCASECMP 429af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany 4303f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { 4310ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#if MAC_INTERPOSE_FUNCTIONS 4320ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko if (!asan_inited) return REAL(strncmp)(s1, s2, size); 4330ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#endif 4341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strncmp is called from malloc_default_purgeable_zone() 4351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 4361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 43709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strncmp)(s1, s2, size); 4381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 4398648e7734ff02a25706464e9e294bd217622bcaeKostya Serebryany ENSURE_ASAN_INITED(); 4401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany unsigned char c1 = 0, c2 = 0; 4413f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr i; 4421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany for (i = 0; i < size; i++) { 4431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c1 = (unsigned char)s1[i]; 4441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c2 = (unsigned char)s2[i]; 4451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (c1 != c2 || c1 == '\0') break; 4461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 4472d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany ASAN_READ_RANGE(s1, Min(i + 1, size)); 4482d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany ASAN_READ_RANGE(s2, Min(i + 1, size)); 4491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return CharCmp(c1, c2); 4501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 4523f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) { 453e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 454cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 455c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1); 456c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size); 4571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(from, from_size); 4581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(to, size); 4591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 46009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strncpy)(to, from, size); 4611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 46381a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#if ASAN_INTERCEPT_STRNLEN 4643f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(uptr, strnlen, const char *s, uptr maxlen) { 465e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 4663f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr length = REAL(strnlen)(s, maxlen); 467cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 4682d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany ASAN_READ_RANGE(s, Min(length + 1, maxlen)); 4691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 4701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return length; 4711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 47281a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#endif // ASAN_INTERCEPT_STRNLEN 473547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 4748f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonovstatic inline bool IsValidStrtolBase(int base) { 4758f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov return (base == 0) || (2 <= base && base <= 36); 4768f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov} 4778f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov 4788f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonovstatic inline void FixRealStrtolEndptr(const char *nptr, char **endptr) { 4793f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany CHECK(endptr != 0); 4808f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov if (nptr == *endptr) { 4818f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov // No digits were found at strtol call, we need to find out the last 4828f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov // symbol accessed by strtoll on our own. 4838f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov // We get this symbol by skipping leading blanks and optional +/- sign. 4848f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov while (IsSpace(*nptr)) nptr++; 4858f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov if (*nptr == '+' || *nptr == '-') nptr++; 4868f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov *endptr = (char*)nptr; 4878f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov } 4888f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov CHECK(*endptr >= nptr); 48984ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov} 49084ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov 491847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long, strtol, const char *nptr, // NOLINT 49284ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov char **endptr, int base) { 49384ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov ENSURE_ASAN_INITED(); 494cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 495847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(strtol)(nptr, endptr, base); 49684ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov } 49784ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov char *real_endptr; 498847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT 4993f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany if (endptr != 0) { 50084ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov *endptr = real_endptr; 50184ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov } 5028f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov if (IsValidStrtolBase(base)) { 5038f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 50484ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 50584ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov } 50684ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov return result; 50784ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov} 50884ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov 509847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(int, atoi, const char *nptr) { 5100ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#if MAC_INTERPOSE_FUNCTIONS 5110ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko if (!asan_inited) return REAL(atoi)(nptr); 5120ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#endif 513847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ENSURE_ASAN_INITED(); 514cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 515847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(atoi)(nptr); 516847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov } 517847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov char *real_endptr; 518847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // "man atoi" tells that behavior of atoi(nptr) is the same as 5193f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the 520847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // parsed integer can't be stored in *long* type (even if it's 521847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // different from int). So, we just imitate this behavior. 522847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov int result = REAL(strtol)(nptr, &real_endptr, 10); 523847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 524847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 525847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return result; 526847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov} 527847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov 528847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long, atol, const char *nptr) { // NOLINT 5290ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#if MAC_INTERPOSE_FUNCTIONS 5300ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko if (!asan_inited) return REAL(atol)(nptr); 5310ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#endif 532847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ENSURE_ASAN_INITED(); 533cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 534847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(atol)(nptr); 535847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov } 536847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov char *real_endptr; 537847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT 538847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 539847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 540847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return result; 541847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov} 542847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov 543847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 544847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT 5458f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov char **endptr, int base) { 5468f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov ENSURE_ASAN_INITED(); 547cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 548847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(strtoll)(nptr, endptr, base); 5498f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov } 5508f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov char *real_endptr; 551847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT 5523f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany if (endptr != 0) { 5538f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov *endptr = real_endptr; 5548f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov } 555847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // If base has unsupported value, strtoll can exit with EINVAL 556847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // without reading any characters. So do additional checks only 557847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // if base is valid. 5588f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov if (IsValidStrtolBase(base)) { 5598f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 5608f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 5618f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov } 5628f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov return result; 5638f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov} 5648f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov 565847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT 566847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ENSURE_ASAN_INITED(); 567cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 568847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(atoll)(nptr); 569847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov } 570847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov char *real_endptr; 571847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT 572847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 573847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 574847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return result; 575847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov} 576847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL 577847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov 578580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov#define ASAN_INTERCEPT_FUNC(name) do { \ 579cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!INTERCEPT_FUNCTION(name) && flags()->verbosity > 0) \ 580580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov Report("AddressSanitizer: failed to intercept '" #name "'\n"); \ 581580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov } while (0) 582580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov 583600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#if defined(_WIN32) 584600972e3427173cc8904d741decd1af0ed5de9fdTimur IskhodzhanovINTERCEPTOR_WINAPI(DWORD, CreateThread, 5853f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany void* security, uptr stack_size, 586600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov DWORD (__stdcall *start_routine)(void*), void* arg, 587600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov DWORD flags, void* tid) { 588600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov GET_STACK_TRACE_HERE(kStackTraceMax); 589e0cff0bc20ae51790c8edfbceb817e18ebf5355eKostya Serebryany u32 current_tid = asanThreadRegistry().GetCurrentTidOrInvalid(); 590600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack); 591600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov asanThreadRegistry().RegisterThread(t); 592600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov return REAL(CreateThread)(security, stack_size, 593600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov asan_thread_start, t, flags, tid); 594600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov} 595600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov 596600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanovnamespace __asan { 597600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanovvoid InitializeWindowsInterceptors() { 598580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(CreateThread); 599600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov} 600600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov 601600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov} // namespace __asan 602600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#endif 603600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov 604547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany// ---------------------- InitializeAsanInterceptors ---------------- {{{1 605547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanynamespace __asan { 606547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanyvoid InitializeAsanInterceptors() { 607fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany static bool was_called_once; 608fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany CHECK(was_called_once == false); 609fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany was_called_once = true; 6100ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#if MAC_INTERPOSE_FUNCTIONS 6110ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko return; 6120ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#endif 61307bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intercept mem* functions. 614580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memcmp); 615580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memmove); 616580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memset); 61738dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { 618580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memcpy); 619573fb4b102dda9d231a8dbd0c01e67e84e9b0874Alexander Potapenko } else { 6200ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#if !MAC_INTERPOSE_FUNCTIONS 621beda44f87166f91dbeef3d174d77395653bead4dAlexander Potapenko // If we're using dynamic interceptors on Mac, these two are just plain 6220ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko // functions. 6230ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko *(uptr*)&REAL(memcpy) = (uptr)REAL(memmove); 6240ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#endif 625573fb4b102dda9d231a8dbd0c01e67e84e9b0874Alexander Potapenko } 62607bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov 62707bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intercept str* functions. 628580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strcat); // NOLINT 629580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strchr); 630580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strcmp); 631580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strcpy); // NOLINT 632580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strlen); 633c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov ASAN_INTERCEPT_FUNC(strncat); 634580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strncmp); 635580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strncpy); 636fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_STRCASECMP_AND_STRNCASECMP 637580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strcasecmp); 638580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strncasecmp); 639fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 640fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_STRDUP 641fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov ASAN_INTERCEPT_FUNC(strdup); 642fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 643fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_STRNLEN 644fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov ASAN_INTERCEPT_FUNC(strnlen); 645fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 646fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_INDEX 647fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov# if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 648580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(index); 64907bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov# else 650619e8bf99d2714c4411fefba22d54c233d93a177Meador Inge CHECK(OVERRIDE_FUNCTION(index, WRAP(strchr))); 65107bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov# endif 65207bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif 6535b29018cf422e7711fb760b733c32127397a43fcAlexey Samsonov 654580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(atoi); 655580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(atol); 656580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strtol); 657847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 658580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(atoll); 659580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strtoll); 66084ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov#endif 66184ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov 662f0c6de3d91ba5cdfbb17a630e823523c7d433160Alexander Potapenko#if ASAN_INTERCEPT_MLOCKX 66300f1c091441be5c2cacb99e21bd1965a5e418242Alexander Potapenko // Intercept mlock/munlock. 66400f1c091441be5c2cacb99e21bd1965a5e418242Alexander Potapenko ASAN_INTERCEPT_FUNC(mlock); 66500f1c091441be5c2cacb99e21bd1965a5e418242Alexander Potapenko ASAN_INTERCEPT_FUNC(munlock); 66600f1c091441be5c2cacb99e21bd1965a5e418242Alexander Potapenko ASAN_INTERCEPT_FUNC(mlockall); 66700f1c091441be5c2cacb99e21bd1965a5e418242Alexander Potapenko ASAN_INTERCEPT_FUNC(munlockall); 668f0c6de3d91ba5cdfbb17a630e823523c7d433160Alexander Potapenko#endif 66900f1c091441be5c2cacb99e21bd1965a5e418242Alexander Potapenko 67007bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intecept signal- and jump-related functions. 671580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(longjmp); 67234a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 673580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(sigaction); 674580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(signal); 675919c24787a655597bdcf367e26c9dd1504e9f463Evgeniy Stepanov#endif 676fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT__LONGJMP 677580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(_longjmp); 678fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 679fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_SIGLONGJMP 680580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(siglongjmp); 681fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 682fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov 683fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov // Intercept exception handling functions. 684fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT___CXA_THROW 685fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov INTERCEPT_FUNCTION(__cxa_throw); 6863e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#endif 6873e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov 68807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intercept threading-related functions 689fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_PTHREAD_CREATE 690580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(pthread_create); 69107bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif 69207bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov 693600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov // Some Windows-specific interceptors. 694600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#if defined(_WIN32) 695600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov InitializeWindowsInterceptors(); 696600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#endif 697600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov 69807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Some Mac-specific interceptors. 69907bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#if defined(__APPLE__) 700beba6448539095b67cab266d09cd7b7d313b8c3dAlexey Samsonov InitializeMacInterceptors(); 701547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#endif 702547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 703cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->verbosity > 0) { 7042962f26071ebef1d5fec52b5569e5ae7aae45c9bAlexander Potapenko Report("AddressSanitizer: libc interceptors initialized\n"); 705547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany } 706547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany} 707547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 708547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany} // namespace __asan 709