asan_interceptors.cc revision 05bf9a51dfeac0f84f6dbc2dacf987249c0fc612
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) { 20952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany ENSURE_ASAN_INITED(); 21052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany unsigned char c1 = 0, c2 = 0; 21152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany const unsigned char *s1 = (const unsigned char*)a1; 21252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany const unsigned char *s2 = (const unsigned char*)a2; 2133f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr i; 21452fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany for (i = 0; i < size; i++) { 21552fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany c1 = s1[i]; 21652fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany c2 = s2[i]; 21752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany if (c1 != c2) break; 21852fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany } 21952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany ASAN_READ_RANGE(s1, Min(i + 1, size)); 22052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany ASAN_READ_RANGE(s2, Min(i + 1, size)); 22152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany return CharCmp(c1, c2); 22252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany} 22352fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany 2243f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) { 2251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // memcpy is called during __asan_init() from the internals 2261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // of printf(...). 2271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 22809672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memcpy)(to, from, size); 2291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 230e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 231cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_intrin) { 232c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany if (to != from) { 233c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany // We do not treat memcpy with to==from as a bug. 234c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany // See http://llvm.org/bugs/show_bug.cgi?id=11763. 235c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); 236c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany } 2371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(from, size); 2381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(to, size); 2391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 24009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memcpy)(to, from, size); 2411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2433f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) { 244a1a25c1afe38e59ffb342c24bb5bb10d05679df7Alexey Samsonov if (asan_init_is_running) { 245a1a25c1afe38e59ffb342c24bb5bb10d05679df7Alexey Samsonov return REAL(memmove)(to, from, size); 246a1a25c1afe38e59ffb342c24bb5bb10d05679df7Alexey Samsonov } 247e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 248cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_intrin) { 2491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(from, size); 2501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(to, size); 2511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 25209672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memmove)(to, from, size); 2531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2553f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(void*, memset, void *block, int c, uptr size) { 256ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko // memset is called inside Printf. 257e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany if (asan_init_is_running) { 25809672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memset)(block, c, size); 259e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany } 260e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 261cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_intrin) { 2621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(block, size); 2631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 26409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memset)(block, c, size); 2651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 267f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strchr, const char *str, int c) { 268e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 26909672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov char *result = REAL(strchr)(str, c); 270cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 2713f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr bytes_read = (result ? result - str : REAL(strlen)(str)) + 1; 2721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(str, bytes_read); 2731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 2741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return result; 2751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 277fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_INDEX 278fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov# if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 2794b0c5f240e71be4f375627e57d0f1b89600918a7Evgeniy StepanovINTERCEPTOR(char*, index, const char *string, int c) 280adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov ALIAS(WRAPPER_NAME(strchr)); 281fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov# else 282b4fefa713da3dabda1cd83ae4182c71f1683f02cAlexey SamsonovDEFINE_REAL(char*, index, const char *string, int c) 283fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov# endif 284fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif // ASAN_INTERCEPT_INDEX 285af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany 28637b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko// For both strcat() and strncat() we need to check the validity of |to| 28737b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko// argument irrespective of the |from| length. 288f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT 2890985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany ENSURE_ASAN_INITED(); 290cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 2913f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr from_length = REAL(strlen)(from); 2920985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany ASAN_READ_RANGE(from, from_length + 1); 29337b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko uptr to_length = REAL(strlen)(to); 29437b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko ASAN_READ_RANGE(to, to_length); 29537b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko ASAN_WRITE_RANGE(to + to_length, from_length + 1); 29637b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko // If the copying actually happens, the |from| string should not overlap 29737b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko // with the resulting string starting at |to|, which has a length of 29837b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko // to_length + from_length + 1. 2990985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany if (from_length > 0) { 30037b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1, 30137b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko from, from_length + 1); 3020985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany } 3030985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany } 30409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strcat)(to, from); // NOLINT 3050985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany} 3060985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany 307c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey SamsonovINTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) { 308c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov ENSURE_ASAN_INITED(); 30937b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko if (flags()->replace_str) { 310c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov uptr from_length = MaybeRealStrnlen(from, size); 31137b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko uptr copy_length = Min(size, from_length + 1); 31237b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko ASAN_READ_RANGE(from, copy_length); 313c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov uptr to_length = REAL(strlen)(to); 314c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov ASAN_READ_RANGE(to, to_length); 315c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov ASAN_WRITE_RANGE(to + to_length, from_length + 1); 316c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov if (from_length > 0) { 31737b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1, 31837b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko from, copy_length); 319c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov } 320c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov } 321c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov return REAL(strncat)(to, from, size); 322c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov} 323c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov 324f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 325fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov if (asan_init_is_running) { 326fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov return REAL(strcmp)(s1, s2); 3271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 3288648e7734ff02a25706464e9e294bd217622bcaeKostya Serebryany ENSURE_ASAN_INITED(); 3291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany unsigned char c1, c2; 3303f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr i; 3311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany for (i = 0; ; i++) { 3321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c1 = (unsigned char)s1[i]; 3331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c2 = (unsigned char)s2[i]; 3341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (c1 != c2 || c1 == '\0') break; 3351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 3361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s1, i + 1); 3371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s2, i + 1); 3381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return CharCmp(c1, c2); 3391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 3401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 341f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT 3421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strcpy is called from malloc_default_purgeable_zone() 3431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 3441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 34509672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strcpy)(to, from); // NOLINT 3461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 347e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 348cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 3493f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr from_size = REAL(strlen)(from) + 1; 350c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size); 3511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(from, from_size); 3521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(to, from_size); 3531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 35409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strcpy)(to, from); // NOLINT 3551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 3561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 357fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_STRDUP 358f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strdup, const char *s) { 359e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 360cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 3613f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr length = REAL(strlen)(s); 3621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s, length + 1); 3631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 36409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strdup)(s); 3651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 366fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 3671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3683f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(uptr, strlen, const char *s) { 3691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strlen is called from malloc_default_purgeable_zone() 3701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 3711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 37209672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strlen)(s); 3731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 374e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 3753f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr length = REAL(strlen)(s); 376cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 3771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s, length + 1); 3781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 3791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return length; 3801e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 3811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 382fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_STRCASECMP_AND_STRNCASECMP 383fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey SamsonovINTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 384fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov ENSURE_ASAN_INITED(); 385fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov unsigned char c1, c2; 386fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov uptr i; 387fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov for (i = 0; ; i++) { 388fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov c1 = (unsigned char)s1[i]; 389fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov c2 = (unsigned char)s2[i]; 390fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 391fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov } 392fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov ASAN_READ_RANGE(s1, i + 1); 393fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov ASAN_READ_RANGE(s2, i + 1); 394fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov return CharCaseCmp(c1, c2); 395fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov} 396fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov 3973f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, uptr n) { 398af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany ENSURE_ASAN_INITED(); 399af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany unsigned char c1 = 0, c2 = 0; 4003f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr i; 401f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov for (i = 0; i < n; i++) { 402af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany c1 = (unsigned char)s1[i]; 403af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany c2 = (unsigned char)s2[i]; 404af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 405af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany } 406f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov ASAN_READ_RANGE(s1, Min(i + 1, n)); 407f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov ASAN_READ_RANGE(s2, Min(i + 1, n)); 408af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany return CharCaseCmp(c1, c2); 409af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany} 410fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif // ASAN_INTERCEPT_STRCASECMP_AND_STRNCASECMP 411af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany 4123f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { 4131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strncmp is called from malloc_default_purgeable_zone() 4141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 4151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 41609672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strncmp)(s1, s2, size); 4171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 4188648e7734ff02a25706464e9e294bd217622bcaeKostya Serebryany ENSURE_ASAN_INITED(); 4191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany unsigned char c1 = 0, c2 = 0; 4203f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr i; 4211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany for (i = 0; i < size; i++) { 4221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c1 = (unsigned char)s1[i]; 4231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c2 = (unsigned char)s2[i]; 4241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (c1 != c2 || c1 == '\0') break; 4251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 4262d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany ASAN_READ_RANGE(s1, Min(i + 1, size)); 4272d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany ASAN_READ_RANGE(s2, Min(i + 1, size)); 4281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return CharCmp(c1, c2); 4291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 4313f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) { 432e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 433cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 434c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1); 435c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size); 4361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(from, from_size); 4371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(to, size); 4381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 43909672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strncpy)(to, from, size); 4401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 44281a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#if ASAN_INTERCEPT_STRNLEN 4433f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(uptr, strnlen, const char *s, uptr maxlen) { 444e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 4453f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr length = REAL(strnlen)(s, maxlen); 446cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 4472d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany ASAN_READ_RANGE(s, Min(length + 1, maxlen)); 4481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 4491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return length; 4501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 45181a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#endif // ASAN_INTERCEPT_STRNLEN 452547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 4538f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonovstatic inline bool IsValidStrtolBase(int base) { 4548f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov return (base == 0) || (2 <= base && base <= 36); 4558f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov} 4568f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov 4578f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonovstatic inline void FixRealStrtolEndptr(const char *nptr, char **endptr) { 4583f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany CHECK(endptr != 0); 4598f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov if (nptr == *endptr) { 4608f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov // No digits were found at strtol call, we need to find out the last 4618f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov // symbol accessed by strtoll on our own. 4628f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov // We get this symbol by skipping leading blanks and optional +/- sign. 4638f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov while (IsSpace(*nptr)) nptr++; 4648f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov if (*nptr == '+' || *nptr == '-') nptr++; 4658f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov *endptr = (char*)nptr; 4668f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov } 4678f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov CHECK(*endptr >= nptr); 46884ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov} 46984ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov 470847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long, strtol, const char *nptr, // NOLINT 47184ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov char **endptr, int base) { 47284ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov ENSURE_ASAN_INITED(); 473cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 474847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(strtol)(nptr, endptr, base); 47584ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov } 47684ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov char *real_endptr; 477847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT 4783f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany if (endptr != 0) { 47984ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov *endptr = real_endptr; 48084ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov } 4818f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov if (IsValidStrtolBase(base)) { 4828f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 48384ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 48484ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov } 48584ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov return result; 48684ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov} 48784ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov 488847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(int, atoi, const char *nptr) { 489847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ENSURE_ASAN_INITED(); 490cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 491847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(atoi)(nptr); 492847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov } 493847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov char *real_endptr; 494847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // "man atoi" tells that behavior of atoi(nptr) is the same as 4953f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the 496847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // parsed integer can't be stored in *long* type (even if it's 497847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // different from int). So, we just imitate this behavior. 498847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov int result = REAL(strtol)(nptr, &real_endptr, 10); 499847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 500847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 501847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return result; 502847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov} 503847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov 504847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long, atol, const char *nptr) { // NOLINT 505847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ENSURE_ASAN_INITED(); 506cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 507847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(atol)(nptr); 508847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov } 509847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov char *real_endptr; 510847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT 511847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 512847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 513847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return result; 514847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov} 515847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov 516847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 517847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT 5188f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov char **endptr, int base) { 5198f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov ENSURE_ASAN_INITED(); 520cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 521847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(strtoll)(nptr, endptr, base); 5228f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov } 5238f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov char *real_endptr; 524847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT 5253f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany if (endptr != 0) { 5268f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov *endptr = real_endptr; 5278f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov } 528847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // If base has unsupported value, strtoll can exit with EINVAL 529847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // without reading any characters. So do additional checks only 530847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // if base is valid. 5318f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov if (IsValidStrtolBase(base)) { 5328f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 5338f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 5348f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov } 5358f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov return result; 5368f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov} 5378f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov 538847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT 539847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ENSURE_ASAN_INITED(); 540cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 541847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(atoll)(nptr); 542847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov } 543847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov char *real_endptr; 544847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT 545847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 546847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 547847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return result; 548847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov} 549847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL 550847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov 551580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov#define ASAN_INTERCEPT_FUNC(name) do { \ 552cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!INTERCEPT_FUNCTION(name) && flags()->verbosity > 0) \ 553580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov Report("AddressSanitizer: failed to intercept '" #name "'\n"); \ 554580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov } while (0) 555580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov 556600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#if defined(_WIN32) 557600972e3427173cc8904d741decd1af0ed5de9fdTimur IskhodzhanovINTERCEPTOR_WINAPI(DWORD, CreateThread, 5583f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany void* security, uptr stack_size, 559600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov DWORD (__stdcall *start_routine)(void*), void* arg, 560600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov DWORD flags, void* tid) { 561600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov GET_STACK_TRACE_HERE(kStackTraceMax); 562e0cff0bc20ae51790c8edfbceb817e18ebf5355eKostya Serebryany u32 current_tid = asanThreadRegistry().GetCurrentTidOrInvalid(); 563600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack); 564600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov asanThreadRegistry().RegisterThread(t); 565600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov return REAL(CreateThread)(security, stack_size, 566600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov asan_thread_start, t, flags, tid); 567600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov} 568600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov 569600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanovnamespace __asan { 570600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanovvoid InitializeWindowsInterceptors() { 571580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(CreateThread); 572600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov} 573600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov 574600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov} // namespace __asan 575600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#endif 576600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov 577547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany// ---------------------- InitializeAsanInterceptors ---------------- {{{1 578547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanynamespace __asan { 579547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanyvoid InitializeAsanInterceptors() { 580fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany static bool was_called_once; 581fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany CHECK(was_called_once == false); 582fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany was_called_once = true; 58307bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intercept mem* functions. 584580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memcmp); 585580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memmove); 586580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memset); 58738dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { 588580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memcpy); 589573fb4b102dda9d231a8dbd0c01e67e84e9b0874Alexander Potapenko } else { 59009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(memcpy) = REAL(memmove); 591573fb4b102dda9d231a8dbd0c01e67e84e9b0874Alexander Potapenko } 59207bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov 59307bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intercept str* functions. 594580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strcat); // NOLINT 595580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strchr); 596580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strcmp); 597580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strcpy); // NOLINT 598580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strlen); 599c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov ASAN_INTERCEPT_FUNC(strncat); 600580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strncmp); 601580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strncpy); 602fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_STRCASECMP_AND_STRNCASECMP 603580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strcasecmp); 604580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strncasecmp); 605fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 606fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_STRDUP 607fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov ASAN_INTERCEPT_FUNC(strdup); 608fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 609fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_STRNLEN 610fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov ASAN_INTERCEPT_FUNC(strnlen); 611fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 612fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_INDEX 613fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov# if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 614580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(index); 61507bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov# else 616619e8bf99d2714c4411fefba22d54c233d93a177Meador Inge CHECK(OVERRIDE_FUNCTION(index, WRAP(strchr))); 61707bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov# endif 61807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif 6195b29018cf422e7711fb760b733c32127397a43fcAlexey Samsonov 620580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(atoi); 621580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(atol); 622580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strtol); 623847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 624580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(atoll); 625580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strtoll); 62684ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov#endif 62784ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov 628f0c6de3d91ba5cdfbb17a630e823523c7d433160Alexander Potapenko#if ASAN_INTERCEPT_MLOCKX 62900f1c091441be5c2cacb99e21bd1965a5e418242Alexander Potapenko // Intercept mlock/munlock. 63000f1c091441be5c2cacb99e21bd1965a5e418242Alexander Potapenko ASAN_INTERCEPT_FUNC(mlock); 63100f1c091441be5c2cacb99e21bd1965a5e418242Alexander Potapenko ASAN_INTERCEPT_FUNC(munlock); 63200f1c091441be5c2cacb99e21bd1965a5e418242Alexander Potapenko ASAN_INTERCEPT_FUNC(mlockall); 63300f1c091441be5c2cacb99e21bd1965a5e418242Alexander Potapenko ASAN_INTERCEPT_FUNC(munlockall); 634f0c6de3d91ba5cdfbb17a630e823523c7d433160Alexander Potapenko#endif 63500f1c091441be5c2cacb99e21bd1965a5e418242Alexander Potapenko 63607bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intecept signal- and jump-related functions. 637580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(longjmp); 63834a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 639580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(sigaction); 640580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(signal); 641919c24787a655597bdcf367e26c9dd1504e9f463Evgeniy Stepanov#endif 642fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT__LONGJMP 643580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(_longjmp); 644fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 645fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_SIGLONGJMP 646580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(siglongjmp); 647fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 648fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov 649fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov // Intercept exception handling functions. 650fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT___CXA_THROW 651fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov INTERCEPT_FUNCTION(__cxa_throw); 6523e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#endif 6533e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov 65407bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intercept threading-related functions 655fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_PTHREAD_CREATE 656580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(pthread_create); 65707bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif 65807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov 659600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov // Some Windows-specific interceptors. 660600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#if defined(_WIN32) 661600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov InitializeWindowsInterceptors(); 662600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#endif 663600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov 66407bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Some Mac-specific interceptors. 66507bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#if defined(__APPLE__) 666beba6448539095b67cab266d09cd7b7d313b8c3dAlexey Samsonov InitializeMacInterceptors(); 667547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#endif 668547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 669cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->verbosity > 0) { 6702962f26071ebef1d5fec52b5569e5ae7aae45c9bAlexander Potapenko Report("AddressSanitizer: libc interceptors initialized\n"); 671547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany } 672547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany} 673547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 674547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany} // namespace __asan 675