asan_interceptors.cc revision 619e8bf99d2714c4411fefba22d54c233d93a177
11e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===-- asan_interceptors.cc ------------------------------------*- C++ -*-===// 21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The LLVM Compiler Infrastructure 41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source 61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details. 71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 12d47189c1b63a4de755d7ec071f8d56c8d01cc667Kostya Serebryany// Intercept various libc functions. 131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_interceptors.h" 151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_allocator.h" 171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_interface.h" 181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h" 191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_mapping.h" 201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stack.h" 211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stats.h" 224803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#include "asan_thread_registry.h" 235b29018cf422e7711fb760b733c32127397a43fcAlexey Samsonov#include "interception/interception.h" 241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2584ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov// Use macro to describe if specific function should be 2684ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov// intercepted on a given platform. 27670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov#if !defined(_WIN32) 28847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov# define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 1 29670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov#else 30847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov# define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 0 31670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov#endif 32670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov 33670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov#if !defined(__APPLE__) 34670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov# define ASAN_INTERCEPT_STRNLEN 1 35670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov#else 36670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov# define ASAN_INTERCEPT_STRNLEN 0 37670439cf36c7335add97aa4de65a397cce9ba849Alexey Samsonov#endif 3884ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov 3934a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#if defined(ANDROID) || defined(_WIN32) 4034a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov# define ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 0 4134a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#else 4234a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov# define ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 1 4334a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#endif 4434a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov 454e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov// Use extern declarations of intercepted functions on Mac and Windows 464e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov// to avoid including system headers. 474e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov#if defined(__APPLE__) || (defined(_WIN32) && !defined(_DLL)) 486ebea222e306fbe53aab78d7781e5ac19be46b5dAlexey Samsonovextern "C" { 4973fe35fa6b4c437c9a723eb7bbad4863c7edbe1eAlexey Samsonov// signal.h 5034a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov# if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 5173fe35fa6b4c437c9a723eb7bbad4863c7edbe1eAlexey Samsonovstruct sigaction; 5273fe35fa6b4c437c9a723eb7bbad4863c7edbe1eAlexey Samsonovint sigaction(int sig, const struct sigaction *act, 5373fe35fa6b4c437c9a723eb7bbad4863c7edbe1eAlexey Samsonov struct sigaction *oldact); 5473fe35fa6b4c437c9a723eb7bbad4863c7edbe1eAlexey Samsonovvoid *signal(int signum, void *handler); 554e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov# endif 566ebea222e306fbe53aab78d7781e5ac19be46b5dAlexey Samsonov 574e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov// setjmp.h 584e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovvoid longjmp(void* env, int value); 594e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov# if !defined(_WIN32) 604e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovvoid _longjmp(void *env, int value); 614e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov# endif 622716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanov 634e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov// string.h / strings.h 644e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovint memcmp(const void *a1, const void *a2, size_t size); 654e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovvoid* memmove(void *to, const void *from, size_t size); 664e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovvoid* memcpy(void *to, const void *from, size_t size); 674e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovvoid* memset(void *block, int c, size_t size); 684e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovchar* strchr(const char *str, int c); 69d01c51d33a5b4c52160c0a6cc18f7739a0a137d3Alexey Samsonov# if defined(__APPLE__) 7056e25249493ff0eeb20d5ab9b2ffe635a7b63ac5Alexey Samsonovchar* index(const char *string, int c); 714e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov# endif 724e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovchar* strcat(char *to, const char* from); // NOLINT 734e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovchar* strcpy(char *to, const char* from); // NOLINT 744e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovchar* strncpy(char *to, const char* from, size_t size); 752716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanovint strcmp(const char *s1, const char* s2); 764e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovint strncmp(const char *s1, const char* s2, size_t size); 7756e25249493ff0eeb20d5ab9b2ffe635a7b63ac5Alexey Samsonov# if !defined(_WIN32) 7856e25249493ff0eeb20d5ab9b2ffe635a7b63ac5Alexey Samsonovint strcasecmp(const char *s1, const char *s2); 7956e25249493ff0eeb20d5ab9b2ffe635a7b63ac5Alexey Samsonovint strncasecmp(const char *s1, const char *s2, size_t n); 8056e25249493ff0eeb20d5ab9b2ffe635a7b63ac5Alexey Samsonovchar* strdup(const char *s); 8156e25249493ff0eeb20d5ab9b2ffe635a7b63ac5Alexey Samsonov# endif 8256e25249493ff0eeb20d5ab9b2ffe635a7b63ac5Alexey Samsonovsize_t strlen(const char *s); 8381a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov# if ASAN_INTERCEPT_STRNLEN 844e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonovsize_t strnlen(const char *s, size_t maxlen); 854e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov# endif 862716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanov 8784ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov// stdlib.h 88847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonovint atoi(const char *nptr); 89847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonovlong atol(const char *nptr); // NOLINT 908f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonovlong strtol(const char *nptr, char **endptr, int base); // NOLINT 91847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov# if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 92847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonovlong long atoll(const char *nptr); // NOLINT 9384ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonovlong long strtoll(const char *nptr, char **endptr, int base); // NOLINT 9484ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov# endif 9584ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov 964e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov// Windows threads. 974e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov# if defined(_WIN32) 982716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanov__declspec(dllimport) 992716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanovvoid* __stdcall CreateThread(void *sec, size_t st, void* start, 1002716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanov void *arg, DWORD fl, DWORD *id); 1014e7abdcc8ed92a56561ed34f36295c6d01204e5dAlexey Samsonov# endif 102a4898423f0f69d9f7f96631e6384695b0c54d9a9Alexey Samsonov 103a4898423f0f69d9f7f96631e6384695b0c54d9a9Alexey Samsonov// Posix threads. 104a4898423f0f69d9f7f96631e6384695b0c54d9a9Alexey Samsonov# if !defined(_WIN32) 105a4898423f0f69d9f7f96631e6384695b0c54d9a9Alexey Samsonovint pthread_create(void *thread, void *attr, void *(*start_routine)(void*), 106a4898423f0f69d9f7f96631e6384695b0c54d9a9Alexey Samsonov void *arg); 107a4898423f0f69d9f7f96631e6384695b0c54d9a9Alexey Samsonov# endif 1082716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanov} // extern "C" 1092716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanov#endif 1102716a61d085a8fdf13a099822720e320414cc4dcTimur Iskhodzhanov 1111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan { 1121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Instruments read/write access to a single byte in memory. 1141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// On error calls __asan_report_error, which aborts the program. 1159f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany#define ACCESS_ADDRESS(address, isWrite) do { \ 1169f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany if (AddressIsPoisoned(address)) { \ 1179f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany GET_CURRENT_PC_BP_SP; \ 1189f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany __asan_report_error(pc, bp, sp, address, isWrite, /* access_size */ 1); \ 1199f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany } \ 1209f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany} while (0) 1211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE, 1231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// and ASAN_WRITE_RANGE as macro instead of function so 1241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// that no extra frames are created, and stack trace contains 1251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// relevant information only. 1261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Instruments read/write access to a memory range. 1281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// More complex implementation is possible, for now just 1291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// checking the first and the last byte of a range. 1301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \ 1311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (size > 0) { \ 1321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany uintptr_t ptr = (uintptr_t)(offset); \ 1339f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany ACCESS_ADDRESS(ptr, isWrite); \ 1349f311bb0919d86ab3df2810dc0b81b70a87677e3Kostya Serebryany ACCESS_ADDRESS(ptr + (size) - 1, isWrite); \ 1351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } \ 136e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 1371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_READ_RANGE(offset, size) do { \ 1391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ACCESS_MEMORY_RANGE(offset, size, false); \ 140e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 1411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define ASAN_WRITE_RANGE(offset, size) do { \ 1431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ACCESS_MEMORY_RANGE(offset, size, true); \ 144e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 1451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Behavior of functions like "memcpy" or "strcpy" is undefined 1471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// if memory intervals overlap. We report error in this case. 1481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Macro is used to avoid creation of new frames. 1490985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryanystatic inline bool RangesOverlap(const char *offset1, size_t length1, 1500985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany const char *offset2, size_t length2) { 1510985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1)); 1521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 153c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \ 1541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany const char *offset1 = (const char*)_offset1; \ 1551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany const char *offset2 = (const char*)_offset2; \ 1560985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany if (RangesOverlap(offset1, length1, offset2, length2)) { \ 157c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany Report("ERROR: AddressSanitizer %s-param-overlap: " \ 1581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany "memory ranges [%p,%p) and [%p, %p) overlap\n", \ 159c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany name, offset1, offset1 + length1, offset2, offset2 + length2); \ 1601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany PRINT_CURRENT_STACK(); \ 1611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ShowStatsAndAbort(); \ 1621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } \ 163e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 1641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 165e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany#define ENSURE_ASAN_INITED() do { \ 166e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany CHECK(!asan_init_is_running); \ 167e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany if (!asan_inited) { \ 168e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany __asan_init(); \ 169e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany } \ 170e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 1711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1728898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonovstatic inline bool IsSpace(int c) { 1738898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov return (c == ' ') || (c == '\n') || (c == '\t') || 1748898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov (c == '\f') || (c == '\r') || (c == '\v'); 1758898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov} 1768898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov 1778898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonovstatic inline bool IsDigit(int c) { 1788898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov return (c >= '0') && (c <= '9'); 1798898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov} 1808898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov 1818898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonovstatic inline int ToLower(int c) { 1828898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c; 1838898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov} 1848898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov 1858898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov// ---------------------- Internal string functions ---------------- {{{1 1868898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov 1878898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonovint64_t internal_simple_strtoll(const char *nptr, char **endptr, int base) { 1888898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov CHECK(base == 10); 1898898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov while (IsSpace(*nptr)) nptr++; 1908898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov int sgn = 1; 1918898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov uint64_t res = 0; 1928898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov bool have_digits = false; 1938898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov char *old_nptr = (char*)nptr; 1948898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov if (*nptr == '+') { 1958898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov sgn = 1; 1968898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov nptr++; 1978898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov } else if (*nptr == '-') { 1988898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov sgn = -1; 1998898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov nptr++; 2008898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov } 2018898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov while (IsDigit(*nptr)) { 202e4092f6780e107797bc6f2c77219a7256f7b04f3Alexey Samsonov res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX; 2038898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov int digit = ((*nptr) - '0'); 204e4092f6780e107797bc6f2c77219a7256f7b04f3Alexey Samsonov res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX; 2058898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov have_digits = true; 2068898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov nptr++; 2078898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov } 2088898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov if (endptr != NULL) { 2098898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov *endptr = (have_digits) ? (char*)nptr : old_nptr; 2108898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov } 2118898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov if (sgn > 0) { 212e4092f6780e107797bc6f2c77219a7256f7b04f3Alexey Samsonov return (int64_t)(Min((uint64_t)INT64_MAX, res)); 2138898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov } else { 214e4092f6780e107797bc6f2c77219a7256f7b04f3Alexey Samsonov return (res > INT64_MAX) ? INT64_MIN : ((int64_t)res * -1); 2158898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov } 2168898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov} 2178898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov 2188898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonovint64_t internal_atoll(const char *nptr) { 2198898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov return internal_simple_strtoll(nptr, (char**)NULL, 10); 2208898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov} 2218898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov 2221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanysize_t internal_strlen(const char *s) { 2231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany size_t i = 0; 2241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany while (s[i]) i++; 2251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return i; 2261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanysize_t internal_strnlen(const char *s, size_t maxlen) { 22981a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#if ASAN_INTERCEPT_STRNLEN 23009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov if (REAL(strnlen) != NULL) { 23109672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strnlen)(s, maxlen); 2321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 233f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov#endif 2341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany size_t i = 0; 2351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany while (i < maxlen && s[i]) i++; 2361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return i; 2371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2395362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanovchar* internal_strchr(const char *s, int c) { 2405362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov while (true) { 2415362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov if (*s == (char)c) 2425362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov return (char*)s; 2435362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov if (*s == 0) 2445362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov return NULL; 2455362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov s++; 2465362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov } 2475362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov} 2485362717f2c121384778429b5cf34712925ad4a9bTimur Iskhodzhanov 249de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyvoid* internal_memchr(const void* s, int c, size_t n) { 250de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany const char* t = (char*)s; 251de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany for (size_t i = 0; i < n; ++i, ++t) 252de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany if (*t == c) 253de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany return (void*)t; 254de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany return NULL; 255de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany} 256de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany 257de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyint internal_memcmp(const void* s1, const void* s2, size_t n) { 258de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany const char* t1 = (char*)s1; 259de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany const char* t2 = (char*)s2; 260de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany for (size_t i = 0; i < n; ++i, ++t1, ++t2) 261de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany if (*t1 != *t2) 262de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany return *t1 < *t2 ? -1 : 1; 263de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany return 0; 264de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany} 265de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany 266ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko// Should not be used in performance-critical places. 267ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenkovoid* internal_memset(void* s, int c, size_t n) { 268ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko // The next line prevents Clang from making a call to memset() instead of the 269ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko // loop below. 270ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko // FIXME: building the runtime with -ffreestanding is a better idea. However 271ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko // there currently are linktime problems due to PR12396. 272ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko char volatile *t = (char*)s; 273ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko for (size_t i = 0; i < n; ++i, ++t) { 274ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko *t = c; 275ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko } 276ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko return s; 277ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko} 278ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko 279a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryanychar *internal_strstr(const char *haystack, const char *needle) { 280a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany // This is O(N^2), but we are not using it in hot places. 281a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany size_t len1 = internal_strlen(haystack); 282a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany size_t len2 = internal_strlen(needle); 283a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany if (len1 < len2) return 0; 284a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany for (size_t pos = 0; pos <= len1 - len2; pos++) { 285a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany if (internal_memcmp(haystack + pos, needle, len2) == 0) 286a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany return (char*)haystack + pos; 287a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany } 288a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany return 0; 289a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany} 290a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany 291a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryanychar *internal_strncat(char *dst, const char *src, size_t n) { 292a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany size_t len = internal_strlen(dst); 293a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany size_t i; 294a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany for (i = 0; i < n && src[i]; i++) 295a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany dst[len + i] = src[i]; 296a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany dst[len + i] = 0; 297a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany return dst; 298a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany} 2991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 300f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryanyint internal_strcmp(const char *s1, const char *s2) { 301f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany while (true) { 302f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany unsigned c1 = *s1; 303f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany unsigned c2 = *s2; 304f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany if (c1 != c2) return (c1 < c2) ? -1 : 1; 305f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany if (c1 == 0) break; 306f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany s1++; 307f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany s2++; 308f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany } 309f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany return 0; 310f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany} 311f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany 3123fe913558354f76707e2c5584559521399854b79Alexander Potapenkochar *internal_strncpy(char *dst, const char *src, size_t n) { 3133fe913558354f76707e2c5584559521399854b79Alexander Potapenko size_t i; 3143fe913558354f76707e2c5584559521399854b79Alexander Potapenko for (i = 0; i < n && src[i]; i++) 3153fe913558354f76707e2c5584559521399854b79Alexander Potapenko dst[i] = src[i]; 3163fe913558354f76707e2c5584559521399854b79Alexander Potapenko return dst; 3173fe913558354f76707e2c5584559521399854b79Alexander Potapenko} 3183fe913558354f76707e2c5584559521399854b79Alexander Potapenko 3191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // namespace __asan 3201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// ---------------------- Wrappers ---------------- {{{1 3221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyusing namespace __asan; // NOLINT 3231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 324600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanovstatic thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { 3254803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany AsanThread *t = (AsanThread*)arg; 3264803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany asanThreadRegistry().SetCurrent(t); 3274803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return t->ThreadStart(); 3284803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3294803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 3306f0452914ec76c786eb865983793bc03b00fc7b6Alexander Potapenko#ifndef _WIN32 331b8ef925563f8dde5be837c4b0569082867c5f14cEvgeniy StepanovINTERCEPTOR(int, pthread_create, void *thread, 332b8ef925563f8dde5be837c4b0569082867c5f14cEvgeniy Stepanov void *attr, void *(*start_routine)(void*), void *arg) { 3339cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov GET_STACK_TRACE_HERE(kStackTraceMax); 3344803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); 33555cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack); 33655cdfc6c5af92560bc0623b5a0d70af71511c3c8Alexey Samsonov asanThreadRegistry().RegisterThread(t); 33709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(pthread_create)(thread, attr, asan_thread_start, t); 3384803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 339919c24787a655597bdcf367e26c9dd1504e9f463Evgeniy Stepanov#endif // !_WIN32 3404803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 34134a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 342f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void*, signal, int signum, void *handler) { 343034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko if (!AsanInterceptsSignal(signum)) { 344034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko return REAL(signal)(signum, handler); 3454803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany } 346034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko return NULL; 3474803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3484803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 349da13ba833b046553f50b54538e4828287ddbf5c0Alexey SamsonovINTERCEPTOR(int, sigaction, int signum, const struct sigaction *act, 350da13ba833b046553f50b54538e4828287ddbf5c0Alexey Samsonov struct sigaction *oldact) { 351034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko if (!AsanInterceptsSignal(signum)) { 352034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko return REAL(sigaction)(signum, act, oldact); 3534803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany } 354034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko return 0; 3554803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 35634a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#elif ASAN_POSIX 35734a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov// We need to have defined REAL(sigaction) on posix systems. 35834a3202a2c22816a6da66959e266a2d078ded37bAlexey SamsonovDEFINE_REAL(int, sigaction, int signum, const struct sigaction *act, 35934a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov struct sigaction *oldact); 36034a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#endif // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 3614803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 362f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, longjmp, void *env, int val) { 363f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany __asan_handle_no_return(); 36409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(longjmp)(env, val); 3654803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3664803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 36707bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#if !defined(_WIN32) 368f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, _longjmp, void *env, int val) { 369f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany __asan_handle_no_return(); 37009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(_longjmp)(env, val); 3714803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3724803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 373f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, siglongjmp, void *env, int val) { 374f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany __asan_handle_no_return(); 37509672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(siglongjmp)(env, val); 3764803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 37707bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif 3784803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 3793389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov#if ASAN_HAS_EXCEPTIONS == 1 3803389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov#ifdef __APPLE__ 3814803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyextern "C" void __cxa_throw(void *a, void *b, void *c); 3823389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov#endif // __APPLE__ 3834803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 384f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { 38509672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov CHECK(REAL(__cxa_throw)); 386f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany __asan_handle_no_return(); 38709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(__cxa_throw)(a, b, c); 3884803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3894803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#endif 3904803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 3914803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// intercept mlock and friends. 3924803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// Since asan maps 16T of RAM, mlock is completely unfriendly to asan. 3934803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany// All functions return 0 (success). 3944803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanystatic void MlockIsUnsupported() { 3954803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany static bool printed = 0; 3964803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany if (printed) return; 3974803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany printed = true; 3984803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n"); 3994803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 4003389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov 401f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonovextern "C" { 4023389b8ea81f51a28365a421b2646d594bac490f5Alexey SamsonovINTERCEPTOR_ATTRIBUTE 4034803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint mlock(const void *addr, size_t len) { 4044803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany MlockIsUnsupported(); 4054803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return 0; 4064803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 4073389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov 4083389b8ea81f51a28365a421b2646d594bac490f5Alexey SamsonovINTERCEPTOR_ATTRIBUTE 4094803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint munlock(const void *addr, size_t len) { 4104803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany MlockIsUnsupported(); 4114803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return 0; 4124803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 4133389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov 4143389b8ea81f51a28365a421b2646d594bac490f5Alexey SamsonovINTERCEPTOR_ATTRIBUTE 4154803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint mlockall(int flags) { 4164803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany MlockIsUnsupported(); 4174803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return 0; 4184803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 4193389b8ea81f51a28365a421b2646d594bac490f5Alexey Samsonov 4203389b8ea81f51a28365a421b2646d594bac490f5Alexey SamsonovINTERCEPTOR_ATTRIBUTE 4214803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanyint munlockall(void) { 4224803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany MlockIsUnsupported(); 4234803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany return 0; 4244803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 4254803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} // extern "C" 4264803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 42752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanystatic inline int CharCmp(unsigned char c1, unsigned char c2) { 42852fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 42952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany} 43052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany 43152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanystatic inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 4328898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov int c1_low = ToLower(c1); 4338898102a6b1479a9af65857ccbbc1c329a4d9187Alexey Samsonov int c2_low = ToLower(c2); 43452fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany return c1_low - c2_low; 43552fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany} 43652fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany 437f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(int, memcmp, const void *a1, const void *a2, size_t size) { 43852fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany ENSURE_ASAN_INITED(); 43952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany unsigned char c1 = 0, c2 = 0; 44052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany const unsigned char *s1 = (const unsigned char*)a1; 44152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany const unsigned char *s2 = (const unsigned char*)a2; 44252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany size_t i; 44352fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany for (i = 0; i < size; i++) { 44452fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany c1 = s1[i]; 44552fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany c2 = s2[i]; 44652fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany if (c1 != c2) break; 44752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany } 44852fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany ASAN_READ_RANGE(s1, Min(i + 1, size)); 44952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany ASAN_READ_RANGE(s2, Min(i + 1, size)); 45052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany return CharCmp(c1, c2); 45152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany} 45252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany 453f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void*, memcpy, void *to, const void *from, size_t size) { 4541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // memcpy is called during __asan_init() from the internals 4551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // of printf(...). 4561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 45709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memcpy)(to, from, size); 4581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 459e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 4601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_intrin) { 461c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany if (to != from) { 462c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany // We do not treat memcpy with to==from as a bug. 463c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany // See http://llvm.org/bugs/show_bug.cgi?id=11763. 464c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); 465c655cfa8dc0fdf5b521e565f6cbdbf7981fba1b2Kostya Serebryany } 4661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(from, size); 4671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(to, size); 4681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 46909672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memcpy)(to, from, size); 4701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 472f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void*, memmove, void *to, const void *from, size_t size) { 473e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 4741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_intrin) { 4751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(from, size); 4761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(to, size); 4771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 47809672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memmove)(to, from, size); 4791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4801e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 481f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void*, memset, void *block, int c, size_t size) { 482ebb9702cff96192c6a6ea963037929ca7ed60eaeAlexander Potapenko // memset is called inside Printf. 483e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany if (asan_init_is_running) { 48409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memset)(block, c, size); 485e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany } 486e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 4871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_intrin) { 4881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(block, size); 4891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 49009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(memset)(block, c, size); 4911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 493f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strchr, const char *str, int c) { 494e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 49509672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov char *result = REAL(strchr)(str, c); 4961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_str) { 49709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov size_t bytes_read = (result ? result - str : REAL(strlen)(str)) + 1; 4981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(str, bytes_read); 4991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 5001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return result; 5011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 5021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 503adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov#ifdef __linux__ 5044b0c5f240e71be4f375627e57d0f1b89600918a7Evgeniy StepanovINTERCEPTOR(char*, index, const char *string, int c) 505adf2b036127d7e887392d9be5b02069b777ee280Alexey Samsonov ALIAS(WRAPPER_NAME(strchr)); 506f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov#else 5074b0c5f240e71be4f375627e57d0f1b89600918a7Evgeniy StepanovDEFINE_REAL(char*, index, const char *string, int c); 508f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov#endif 509f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov 510f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 511af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany ENSURE_ASAN_INITED(); 512af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany unsigned char c1, c2; 513af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany size_t i; 514af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany for (i = 0; ; i++) { 515af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany c1 = (unsigned char)s1[i]; 516af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany c2 = (unsigned char)s2[i]; 517af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 518af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany } 519af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany ASAN_READ_RANGE(s1, i + 1); 520af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany ASAN_READ_RANGE(s2, i + 1); 521af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany return CharCaseCmp(c1, c2); 522af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany} 523af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany 524f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT 5250985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany ENSURE_ASAN_INITED(); 5260985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany if (FLAG_replace_str) { 52709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov size_t from_length = REAL(strlen)(from); 5280985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany ASAN_READ_RANGE(from, from_length + 1); 5290985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany if (from_length > 0) { 53009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov size_t to_length = REAL(strlen)(to); 5310985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany ASAN_READ_RANGE(to, to_length); 5320985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany ASAN_WRITE_RANGE(to + to_length, from_length + 1); 533c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany CHECK_RANGES_OVERLAP("strcat", to, to_length + 1, from, from_length + 1); 5340985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany } 5350985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany } 53609672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strcat)(to, from); // NOLINT 5370985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany} 5380985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany 539f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 540f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany if (!asan_inited) { 541f3810ea150e140f49bd62123885df922fe3c3b81Kostya Serebryany return internal_strcmp(s1, s2); 5421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 5431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany unsigned char c1, c2; 5441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany size_t i; 5451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany for (i = 0; ; i++) { 5461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c1 = (unsigned char)s1[i]; 5471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c2 = (unsigned char)s2[i]; 5481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (c1 != c2 || c1 == '\0') break; 5491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 5501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s1, i + 1); 5511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s2, i + 1); 5521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return CharCmp(c1, c2); 5531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 5541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 555f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT 5561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strcpy is called from malloc_default_purgeable_zone() 5571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 5581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 55909672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strcpy)(to, from); // NOLINT 5601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 561e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 5621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_str) { 56309672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov size_t from_size = REAL(strlen)(from) + 1; 564c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size); 5651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(from, from_size); 5661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(to, from_size); 5671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 56809672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strcpy)(to, from); // NOLINT 5691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 5701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 571f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strdup, const char *s) { 572e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 5731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_str) { 57409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov size_t length = REAL(strlen)(s); 5751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s, length + 1); 5761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 57709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strdup)(s); 5781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 5791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 580f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(size_t, strlen, const char *s) { 5811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strlen is called from malloc_default_purgeable_zone() 5821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 5831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 58409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strlen)(s); 5851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 586e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 58709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov size_t length = REAL(strlen)(s); 5881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_str) { 5891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(s, length + 1); 5901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 5911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return length; 5921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 5931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 594f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, size_t n) { 595af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany ENSURE_ASAN_INITED(); 596af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany unsigned char c1 = 0, c2 = 0; 597af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany size_t i; 598f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov for (i = 0; i < n; i++) { 599af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany c1 = (unsigned char)s1[i]; 600af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany c2 = (unsigned char)s2[i]; 601af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 602af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany } 603f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov ASAN_READ_RANGE(s1, Min(i + 1, n)); 604f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov ASAN_READ_RANGE(s2, Min(i + 1, n)); 605af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany return CharCaseCmp(c1, c2); 606af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany} 607af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany 608f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(int, strncmp, const char *s1, const char *s2, size_t size) { 6091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strncmp is called from malloc_default_purgeable_zone() 6101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 6111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 61209672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strncmp)(s1, s2, size); 6131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 6141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany unsigned char c1 = 0, c2 = 0; 6151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany size_t i; 6161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany for (i = 0; i < size; i++) { 6171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c1 = (unsigned char)s1[i]; 6181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany c2 = (unsigned char)s2[i]; 6191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (c1 != c2 || c1 == '\0') break; 6201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 6212d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany ASAN_READ_RANGE(s1, Min(i + 1, size)); 6222d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany ASAN_READ_RANGE(s2, Min(i + 1, size)); 6231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return CharCmp(c1, c2); 6241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 6251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 626f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strncpy, char *to, const char *from, size_t size) { 627e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 6281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_str) { 6292d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany size_t from_size = Min(size, internal_strnlen(from, size) + 1); 630c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size); 6311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_READ_RANGE(from, from_size); 6321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany ASAN_WRITE_RANGE(to, size); 6331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 63409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strncpy)(to, from, size); 6351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 6361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 63781a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#if ASAN_INTERCEPT_STRNLEN 638f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(size_t, strnlen, const char *s, size_t maxlen) { 639e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 64009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov size_t length = REAL(strnlen)(s, maxlen); 6411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_replace_str) { 6422d8b3bdb112ebb8ed3f15ee41d4cebcd683b41b0Kostya Serebryany ASAN_READ_RANGE(s, Min(length + 1, maxlen)); 6431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 6441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return length; 6451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 64681a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#endif // ASAN_INTERCEPT_STRNLEN 647547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 6488f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonovstatic inline bool IsValidStrtolBase(int base) { 6498f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov return (base == 0) || (2 <= base && base <= 36); 6508f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov} 6518f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov 6528f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonovstatic inline void FixRealStrtolEndptr(const char *nptr, char **endptr) { 6538f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov CHECK(endptr != NULL); 6548f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov if (nptr == *endptr) { 6558f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov // No digits were found at strtol call, we need to find out the last 6568f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov // symbol accessed by strtoll on our own. 6578f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov // We get this symbol by skipping leading blanks and optional +/- sign. 6588f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov while (IsSpace(*nptr)) nptr++; 6598f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov if (*nptr == '+' || *nptr == '-') nptr++; 6608f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov *endptr = (char*)nptr; 6618f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov } 6628f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov CHECK(*endptr >= nptr); 66384ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov} 66484ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov 665847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long, strtol, const char *nptr, // NOLINT 66684ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov char **endptr, int base) { 66784ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov ENSURE_ASAN_INITED(); 66884ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov if (!FLAG_replace_str) { 669847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(strtol)(nptr, endptr, base); 67084ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov } 67184ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov char *real_endptr; 672847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT 67384ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov if (endptr != NULL) { 67484ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov *endptr = real_endptr; 67584ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov } 6768f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov if (IsValidStrtolBase(base)) { 6778f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 67884ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 67984ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov } 68084ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov return result; 68184ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov} 68284ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov 683847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(int, atoi, const char *nptr) { 684847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ENSURE_ASAN_INITED(); 685847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov if (!FLAG_replace_str) { 686847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(atoi)(nptr); 687847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov } 688847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov char *real_endptr; 689847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // "man atoi" tells that behavior of atoi(nptr) is the same as 690847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // strtol(nptr, NULL, 10), i.e. it sets errno to ERANGE if the 691847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // parsed integer can't be stored in *long* type (even if it's 692847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // different from int). So, we just imitate this behavior. 693847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov int result = REAL(strtol)(nptr, &real_endptr, 10); 694847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 695847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 696847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return result; 697847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov} 698847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov 699847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long, atol, const char *nptr) { // NOLINT 700847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ENSURE_ASAN_INITED(); 701847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov if (!FLAG_replace_str) { 702847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(atol)(nptr); 703847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov } 704847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov char *real_endptr; 705847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT 706847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 707847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 708847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return result; 709847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov} 710847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov 711847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 712847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT 7138f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov char **endptr, int base) { 7148f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov ENSURE_ASAN_INITED(); 7158f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov if (!FLAG_replace_str) { 716847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(strtoll)(nptr, endptr, base); 7178f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov } 7188f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov char *real_endptr; 719847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT 7208f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov if (endptr != NULL) { 7218f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov *endptr = real_endptr; 7228f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov } 723847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // If base has unsupported value, strtoll can exit with EINVAL 724847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // without reading any characters. So do additional checks only 725847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // if base is valid. 7268f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov if (IsValidStrtolBase(base)) { 7278f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 7288f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 7298f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov } 7308f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov return result; 7318f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov} 7328f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov 733847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT 734847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ENSURE_ASAN_INITED(); 735847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov if (!FLAG_replace_str) { 736847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(atoll)(nptr); 737847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov } 738847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov char *real_endptr; 739847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT 740847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 741847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 742847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return result; 743847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov} 744847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL 745847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov 746580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov#define ASAN_INTERCEPT_FUNC(name) do { \ 747580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov if (!INTERCEPT_FUNCTION(name) && FLAG_v > 0) \ 748580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov Report("AddressSanitizer: failed to intercept '" #name "'\n"); \ 749580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov } while (0) 750580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov 751600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#if defined(_WIN32) 752600972e3427173cc8904d741decd1af0ed5de9fdTimur IskhodzhanovINTERCEPTOR_WINAPI(DWORD, CreateThread, 753600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov void* security, size_t stack_size, 754600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov DWORD (__stdcall *start_routine)(void*), void* arg, 755600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov DWORD flags, void* tid) { 756600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov GET_STACK_TRACE_HERE(kStackTraceMax); 757600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); 758600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack); 759600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov asanThreadRegistry().RegisterThread(t); 760600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov return REAL(CreateThread)(security, stack_size, 761600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov asan_thread_start, t, flags, tid); 762600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov} 763600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov 764600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanovnamespace __asan { 765600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanovvoid InitializeWindowsInterceptors() { 766580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(CreateThread); 767600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov} 768600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov 769600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov} // namespace __asan 770600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#endif 771600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov 772547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany// ---------------------- InitializeAsanInterceptors ---------------- {{{1 773547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanynamespace __asan { 774547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanyvoid InitializeAsanInterceptors() { 775fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany static bool was_called_once; 776fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany CHECK(was_called_once == false); 777fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany was_called_once = true; 77807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intercept mem* functions. 779580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memcmp); 780580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memmove); 781580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memset); 78238dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { 783580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memcpy); 784573fb4b102dda9d231a8dbd0c01e67e84e9b0874Alexander Potapenko } else { 78509672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(memcpy) = REAL(memmove); 786573fb4b102dda9d231a8dbd0c01e67e84e9b0874Alexander Potapenko } 78707bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov 78807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intercept str* functions. 789580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strcat); // NOLINT 790580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strchr); 791580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strcmp); 792580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strcpy); // NOLINT 793580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strlen); 794580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strncmp); 795580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strncpy); 79607bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#if !defined(_WIN32) 797580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strcasecmp); 798580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strdup); 799580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strncasecmp); 80007bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov# ifndef __APPLE__ 801580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(index); 80207bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov# else 803619e8bf99d2714c4411fefba22d54c233d93a177Meador Inge CHECK(OVERRIDE_FUNCTION(index, WRAP(strchr))); 80407bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov# endif 80507bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif 80681a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#if ASAN_INTERCEPT_STRNLEN 807580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strnlen); 80807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif 8095b29018cf422e7711fb760b733c32127397a43fcAlexey Samsonov 810580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(atoi); 811580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(atol); 812580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strtol); 813847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 814580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(atoll); 815580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strtoll); 81684ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov#endif 81784ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov 81807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intecept signal- and jump-related functions. 819580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(longjmp); 82034a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 821580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(sigaction); 822580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(signal); 823919c24787a655597bdcf367e26c9dd1504e9f463Evgeniy Stepanov#endif 824919c24787a655597bdcf367e26c9dd1504e9f463Evgeniy Stepanov 82507bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#if !defined(_WIN32) 826580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(_longjmp); 8275b29018cf422e7711fb760b733c32127397a43fcAlexey Samsonov INTERCEPT_FUNCTION(__cxa_throw); 82807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov# if !defined(__APPLE__) 82907bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it 83007bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // there. 831580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(siglongjmp); 83207bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov# endif 8333e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#endif 8343e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov 83507bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intercept threading-related functions 83607bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#if !defined(_WIN32) 837580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(pthread_create); 83807bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif 83907bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov 840600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov // Some Windows-specific interceptors. 841600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#if defined(_WIN32) 842600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov InitializeWindowsInterceptors(); 843600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov#endif 844600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov 84507bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Some Mac-specific interceptors. 84607bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#if defined(__APPLE__) 847beba6448539095b67cab266d09cd7b7d313b8c3dAlexey Samsonov InitializeMacInterceptors(); 848547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany#endif 849547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 850547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany if (FLAG_v > 0) { 8512962f26071ebef1d5fec52b5569e5ae7aae45c9bAlexander Potapenko Report("AddressSanitizer: libc interceptors initialized\n"); 852547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany } 853547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany} 854547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 855547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany} // namespace __asan 856