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" 171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h" 181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_mapping.h" 197e8434940a1fe7dce531d4c458ccd714da48f609Alexey Samsonov#include "asan_poisoning.h" 20487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov#include "asan_report.h" 211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stack.h" 221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stats.h" 2386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#include "asan_suppressions.h" 24c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov#include "sanitizer_common/sanitizer_libc.h" 25c0d78c1de1f2607c874020d27b72cf989c5ce092Alexey Samsonov 26909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar#if SANITIZER_POSIX 27909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar#include "sanitizer_common/sanitizer_posix.h" 28909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar#endif 29909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar 301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan { 311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 32a84805f1ccb2b7d4b6c0ba384bd3541fa4eaf808Kostya Serebryany// Return true if we can quickly decide that the region is unpoisoned. 33a84805f1ccb2b7d4b6c0ba384bd3541fa4eaf808Kostya Serebryanystatic inline bool QuickCheckForUnpoisonedRegion(uptr beg, uptr size) { 34a84805f1ccb2b7d4b6c0ba384bd3541fa4eaf808Kostya Serebryany if (size == 0) return true; 35a84805f1ccb2b7d4b6c0ba384bd3541fa4eaf808Kostya Serebryany if (size <= 32) 36a84805f1ccb2b7d4b6c0ba384bd3541fa4eaf808Kostya Serebryany return !AddressIsPoisoned(beg) && 37a84805f1ccb2b7d4b6c0ba384bd3541fa4eaf808Kostya Serebryany !AddressIsPoisoned(beg + size - 1) && 38a84805f1ccb2b7d4b6c0ba384bd3541fa4eaf808Kostya Serebryany !AddressIsPoisoned(beg + size / 2); 39a84805f1ccb2b7d4b6c0ba384bd3541fa4eaf808Kostya Serebryany return false; 40a84805f1ccb2b7d4b6c0ba384bd3541fa4eaf808Kostya Serebryany} 41a84805f1ccb2b7d4b6c0ba384bd3541fa4eaf808Kostya Serebryany 4286277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstruct AsanInterceptorContext { 4386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines const char *interceptor_name; 4486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines}; 4586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE, 471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// and ASAN_WRITE_RANGE as macro instead of function so 481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// that no extra frames are created, and stack trace contains 491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// relevant information only. 50eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany// We check all shadow bytes. 5186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define ACCESS_MEMORY_RANGE(ctx, offset, size, isWrite) do { \ 52589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov uptr __offset = (uptr)(offset); \ 53589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov uptr __size = (uptr)(size); \ 541b057b20db71ec6cc2bac460c8b2848f0889d47dKostya Serebryany uptr __bad = 0; \ 552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (__offset > __offset + __size) { \ 562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines GET_STACK_TRACE_FATAL_HERE; \ 572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ReportStringFunctionSizeOverflow(__offset, __size, &stack); \ 582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } \ 59a84805f1ccb2b7d4b6c0ba384bd3541fa4eaf808Kostya Serebryany if (!QuickCheckForUnpoisonedRegion(__offset, __size) && \ 601b057b20db71ec6cc2bac460c8b2848f0889d47dKostya Serebryany (__bad = __asan_region_is_poisoned(__offset, __size))) { \ 6186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines AsanInterceptorContext *_ctx = (AsanInterceptorContext *)ctx; \ 6286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines bool suppressed = false; \ 6386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (_ctx) { \ 6486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines suppressed = IsInterceptorSuppressed(_ctx->interceptor_name); \ 6586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!suppressed && HaveStackTraceBasedSuppressions()) { \ 6686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines GET_STACK_TRACE_FATAL_HERE; \ 6786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines suppressed = IsStackTraceSuppressed(&stack); \ 6886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } \ 6986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } \ 7086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!suppressed) { \ 7186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines GET_CURRENT_PC_BP_SP; \ 727c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar __asan_report_error(pc, bp, sp, __bad, isWrite, __size, 0); \ 7386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } \ 74589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov } \ 75589dcdaa520de1033a0f6112c9b67ab9eb7931afEvgeniy Stepanov } while (0) 761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 7786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define ASAN_READ_RANGE(ctx, offset, size) \ 7886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ACCESS_MEMORY_RANGE(ctx, offset, size, false) 7986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define ASAN_WRITE_RANGE(ctx, offset, size) \ 8086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ACCESS_MEMORY_RANGE(ctx, offset, size, true) 811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 82909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar#define ASAN_READ_STRING_OF_LEN(ctx, s, len, n) \ 83909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar ASAN_READ_RANGE((ctx), (s), \ 84909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar common_flags()->strict_string_checks ? (len) + 1 : (n)) 85909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar 86909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar#define ASAN_READ_STRING(ctx, s, n) \ 87909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar ASAN_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n)) 88909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar 891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Behavior of functions like "memcpy" or "strcpy" is undefined 901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// if memory intervals overlap. We report error in this case. 911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Macro is used to avoid creation of new frames. 923f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanystatic inline bool RangesOverlap(const char *offset1, uptr length1, 933f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany const char *offset2, uptr length2) { 940985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1)); 951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 96c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \ 971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany const char *offset1 = (const char*)_offset1; \ 981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany const char *offset2 = (const char*)_offset2; \ 990985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany if (RangesOverlap(offset1, length1, offset2, length2)) { \ 100a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_FATAL_HERE; \ 101487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \ 102487fee7f6f7497906a00d7d2fe2c75e6d5d4feb1Alexey Samsonov offset2, length2, &stack); \ 1031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } \ 104e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany} while (0) 1051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 106c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonovstatic inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) { 10781a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#if ASAN_INTERCEPT_STRNLEN 1083f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany if (REAL(strnlen) != 0) { 10909672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strnlen)(s, maxlen); 1101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 111f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov#endif 112c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov return internal_strnlen(s, maxlen); 113a4ccf878e464d29a4a18756c5c4f626dc530a12eKostya Serebryany} 1141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 115c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryanyvoid SetThreadName(const char *name) { 11689c1384464848c1ad041becf8b97936fa10de21bAlexey Samsonov AsanThread *t = GetCurrentThread(); 117c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany if (t) 118def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov asanThreadRegistry().SetThreadName(t->tid(), name); 119c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany} 120c20b321d49f0eff60f1394d56e623d8ca94f24d7Kostya Serebryany 1218cde99fb9df913aaf7c1715cd134110dd5a15834Dmitry Vyukovint OnExit() { 12214dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov // FIXME: ask frontend whether we need to return failure. 12314dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov return 0; 12414dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov} 12514dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov 1261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // namespace __asan 1271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// ---------------------- Wrappers ---------------- {{{1 1291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyusing namespace __asan; // NOLINT 1301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 13112eb79dd701d9d40551759330a9257316601373bEvgeniy StepanovDECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr) 13212eb79dd701d9d40551759330a9257316601373bEvgeniy StepanovDECLARE_REAL_AND_INTERCEPTOR(void, free, void *) 13312eb79dd701d9d40551759330a9257316601373bEvgeniy Stepanov 13486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define ASAN_INTERCEPTOR_ENTER(ctx, func) \ 13586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines AsanInterceptorContext _ctx = {#func}; \ 13686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ctx = (void *)&_ctx; \ 13786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines (void) ctx; \ 13886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 139a537ea99d3dcc4b2dc0033aee7ad5cb1b378efc7Evgeniy Stepanov#define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name) 14082a9080eaff95d69b270cd863e9df63e3b4e59adEvgeniy Stepanov#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ 14186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_WRITE_RANGE(ctx, ptr, size) 14286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \ 14386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, ptr, size) 1442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ 14586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, func); \ 1462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines do { \ 1472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (asan_init_is_running) \ 1482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return REAL(func)(__VA_ARGS__); \ 1492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (SANITIZER_MAC && UNLIKELY(!asan_inited)) \ 1502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return REAL(func)(__VA_ARGS__); \ 1512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ENSURE_ASAN_INITED(); \ 1529d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov } while (false) 15386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \ 15486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines do { \ 15586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } while (false) 1569d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \ 1579d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov do { \ 1589d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov } while (false) 1599d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \ 1609d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov do { \ 1619d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov } while (false) 1629d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \ 1639d1525ec52430d0b8ffd6d0893b7f5529105b321Evgeniy Stepanov do { \ 16482a9080eaff95d69b270cd863e9df63e3b4e59adEvgeniy Stepanov } while (false) 165996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name) 166e767e350b1a6461bc29cfea28af75f908d7da56eDmitry Vyukov// Should be asanThreadRegistry().SetThreadNameByUserId(thread, name) 167e767e350b1a6461bc29cfea28af75f908d7da56eDmitry Vyukov// But asan does not remember UserId's for threads (pthread_t); 168e767e350b1a6461bc29cfea28af75f908d7da56eDmitry Vyukov// and remembers all ever existed threads, so the linear search by UserId 169e767e350b1a6461bc29cfea28af75f908d7da56eDmitry Vyukov// can be slow. 1705cf2c460e96e593b1c772f1b02d3a217f4837fdcDmitry Vyukov#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \ 171e767e350b1a6461bc29cfea28af75f908d7da56eDmitry Vyukov do { \ 172e767e350b1a6461bc29cfea28af75f908d7da56eDmitry Vyukov } while (false) 173e18e3f07802c420eb4b2da407e148084b75cecc9Evgeniy Stepanov#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name) 17486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// Strict init-order checking is dlopen-hostile: 17586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// https://code.google.com/p/address-sanitizer/issues/detail?id=178 17686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \ 17786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (flags()->strict_init_order) { \ 17886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines StopInitOrderChecking(); \ 17986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 18014dd980b384ad859099b499e12f320c4791fb674Dmitry Vyukov#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit() 18186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \ 18286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines CoverageUpdateMapping() 18386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() CoverageUpdateMapping() 1846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!asan_inited) 1854f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov#include "sanitizer_common/sanitizer_common_interceptors.inc" 1868530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany 18786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// Syscall interceptors don't have contexts, we don't support suppressions 18886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// for them. 18986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(nullptr, p, s) 19086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(nullptr, p, s) 191ae4e6fd0300b13812a02a779619b1a451478cdd1Evgeniy Stepanov#define COMMON_SYSCALL_POST_READ_RANGE(p, s) \ 192ae4e6fd0300b13812a02a779619b1a451478cdd1Evgeniy Stepanov do { \ 193dfab31b93e954ee42622a13dd79e9e1092346035Evgeniy Stepanov (void)(p); \ 194dfab31b93e954ee42622a13dd79e9e1092346035Evgeniy Stepanov (void)(s); \ 195ae4e6fd0300b13812a02a779619b1a451478cdd1Evgeniy Stepanov } while (false) 196ae4e6fd0300b13812a02a779619b1a451478cdd1Evgeniy Stepanov#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \ 197ae4e6fd0300b13812a02a779619b1a451478cdd1Evgeniy Stepanov do { \ 198dfab31b93e954ee42622a13dd79e9e1092346035Evgeniy Stepanov (void)(p); \ 199dfab31b93e954ee42622a13dd79e9e1092346035Evgeniy Stepanov (void)(s); \ 200ae4e6fd0300b13812a02a779619b1a451478cdd1Evgeniy Stepanov } while (false) 201881b677c189e65872fd315a75a0e56f077339189Evgeniy Stepanov#include "sanitizer_common/sanitizer_common_syscalls.inc" 202881b677c189e65872fd315a75a0e56f077339189Evgeniy Stepanov 20386277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstruct ThreadStartParam { 20486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines atomic_uintptr_t t; 20586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines atomic_uintptr_t is_registered; 20686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines}; 20786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 208600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanovstatic thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { 20986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ThreadStartParam *param = reinterpret_cast<ThreadStartParam *>(arg); 21086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines AsanThread *t = nullptr; 21186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines while ((t = reinterpret_cast<AsanThread *>( 21286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines atomic_load(¶m->t, memory_order_acquire))) == 0) 21386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_sched_yield(); 21486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines SetCurrentThread(t); 21586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return t->ThreadStart(GetTid(), ¶m->is_registered); 2164803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 2174803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 218fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_PTHREAD_CREATE 219b8ef925563f8dde5be837c4b0569082867c5f14cEvgeniy StepanovINTERCEPTOR(int, pthread_create, void *thread, 220b8ef925563f8dde5be837c4b0569082867c5f14cEvgeniy Stepanov void *attr, void *(*start_routine)(void*), void *arg) { 221c6ac98d7fcc81768b2ef7ddc785c27e3fc1bdef6Sergey Matveev EnsureMainThreadIDIsCorrect(); 22286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Strict init-order checking is thread-hostile. 2239465cbdbe73590746b57916f46ea1aa4bf3dd13dAlexey Samsonov if (flags()->strict_init_order) 2249465cbdbe73590746b57916f46ea1aa4bf3dd13dAlexey Samsonov StopInitOrderChecking(); 225a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; 226def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov int detached = 0; 227def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov if (attr != 0) 228bb6bc9a0ae534ada3c0c2c226462c351c078d761Evgeniy Stepanov REAL(pthread_attr_getdetachstate)(attr, &detached); 22986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ThreadStartParam param; 23086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines atomic_store(¶m.t, 0, memory_order_relaxed); 23186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines atomic_store(¶m.is_registered, 0, memory_order_relaxed); 23286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines int result = REAL(pthread_create)(thread, attr, asan_thread_start, ¶m); 23386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (result == 0) { 23486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines u32 current_tid = GetCurrentTidOrInvalid(); 23586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines AsanThread *t = 23686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines AsanThread::Create(start_routine, arg, current_tid, &stack, detached); 23786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines atomic_store(¶m.t, reinterpret_cast<uptr>(t), memory_order_release); 23886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Wait until the AsanThread object is initialized and the ThreadRegistry 23986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // entry is in "started" state. One reason for this is that after this 24086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // interceptor exits, the child thread's stack may be the only thing holding 24186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // the |arg| pointer. This may cause LSan to report a leak if leak checking 24286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // happens at a point when the interceptor has already exited, but the stack 24386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // range for the child thread is not yet known. 24486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines while (atomic_load(¶m.is_registered, memory_order_acquire) == 0) 24586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_sched_yield(); 24686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 24786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return result; 24886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines} 249def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov 25086277eb844c4983c81de62d7c050e92fe7155788Stephen HinesINTERCEPTOR(int, pthread_join, void *t, void **arg) { 25186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return real_pthread_join(t, arg); 2524803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 25386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 25486277eb844c4983c81de62d7c050e92fe7155788Stephen HinesDEFINE_REAL_PTHREAD_FUNCTIONS 255fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif // ASAN_INTERCEPT_PTHREAD_CREATE 2564803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 25734a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 2582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 2592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_ANDROID 2602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void*, bsd_signal, int signum, void *handler) { 26186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!IsDeadlySignal(signum) || common_flags()->allow_user_segv_handler) { 2622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return REAL(bsd_signal)(signum, handler); 2632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 2642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 0; 2652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 2662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else 267f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void*, signal, int signum, void *handler) { 26886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!IsDeadlySignal(signum) || common_flags()->allow_user_segv_handler) { 269034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko return REAL(signal)(signum, handler); 2704803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany } 2713f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany return 0; 2724803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 2732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 2744803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 275da13ba833b046553f50b54538e4828287ddbf5c0Alexey SamsonovINTERCEPTOR(int, sigaction, int signum, const struct sigaction *act, 276da13ba833b046553f50b54538e4828287ddbf5c0Alexey Samsonov struct sigaction *oldact) { 27786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!IsDeadlySignal(signum) || common_flags()->allow_user_segv_handler) { 278034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko return REAL(sigaction)(signum, act, oldact); 2794803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany } 280034bda5eab7cda14fac0bed3a39de4a3dbce3cffAlexander Potapenko return 0; 2814803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 2822d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 2832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesnamespace __sanitizer { 2842d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesint real_sigaction(int signum, const void *act, void *oldact) { 2856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines return REAL(sigaction)(signum, (const struct sigaction *)act, 2866d1862363c88c183b0ed7740fca876342cf0474bStephen Hines (struct sigaction *)oldact); 2872d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 2882d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} // namespace __sanitizer 2892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 290e1ba0009d5be18d513ffd29c1b6fccea1a3bffa0Evgeniy Stepanov#elif SANITIZER_POSIX 29134a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov// We need to have defined REAL(sigaction) on posix systems. 29234a3202a2c22816a6da66959e266a2d078ded37bAlexey SamsonovDEFINE_REAL(int, sigaction, int signum, const struct sigaction *act, 293fdde5a97a71b142297d7b2270c2a7f564a37dbaeAlexey Samsonov struct sigaction *oldact) 29434a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#endif // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 2954803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 2960870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov#if ASAN_INTERCEPT_SWAPCONTEXT 29757db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonovstatic void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) { 29857db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov // Align to page size. 29957db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov uptr PageSize = GetPageSizeCached(); 30057db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov uptr bottom = stack & ~(PageSize - 1); 30157db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov ssize += stack - bottom; 30257db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov ssize = RoundUpTo(ssize, PageSize); 30357db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov static const uptr kMaxSaneContextStackSize = 1 << 22; // 4 Mb 304909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar if (AddrIsInMem(bottom) && ssize && ssize <= kMaxSaneContextStackSize) { 30557db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov PoisonShadow(bottom, ssize, 0); 30657db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov } 30757db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov} 30857db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov 3090870028410087e67a0049c76cb7c64f02c260d24Alexey SamsonovINTERCEPTOR(int, swapcontext, struct ucontext_t *oucp, 3100870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov struct ucontext_t *ucp) { 3110870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov static bool reported_warning = false; 3120870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov if (!reported_warning) { 3130870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov Report("WARNING: ASan doesn't fully support makecontext/swapcontext " 3140870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov "functions and may produce false positives in some cases!\n"); 3150870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov reported_warning = true; 3160870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov } 3170870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov // Clear shadow memory for new context (it may share stack 3180870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov // with current context). 31957db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov uptr stack, ssize; 32057db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov ReadContextStack(ucp, &stack, &ssize); 32157db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov ClearShadowMemoryForContextStack(stack, ssize); 3220870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov int res = REAL(swapcontext)(oucp, ucp); 3230870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov // swapcontext technically does not return, but program may swap context to 3240870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov // "oucp" later, that would look as if swapcontext() returned 0. 3250870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov // We need to clear shadow for ucp once again, as it may be in arbitrary 3260870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov // state. 32757db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov ClearShadowMemoryForContextStack(stack, ssize); 3280870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov return res; 3290870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov} 33057db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov#endif // ASAN_INTERCEPT_SWAPCONTEXT 3310870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov 332f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, longjmp, void *env, int val) { 333f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany __asan_handle_no_return(); 33409672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(longjmp)(env, val); 3354803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3364803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 337fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT__LONGJMP 338f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, _longjmp, void *env, int val) { 339f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany __asan_handle_no_return(); 34009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(_longjmp)(env, val); 3414803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 342fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 3434803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 344fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_SIGLONGJMP 345f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, siglongjmp, void *env, int val) { 346f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany __asan_handle_no_return(); 34709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(siglongjmp)(env, val); 3484803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 34907bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif 3504803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 351fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT___CXA_THROW 352f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { 35309672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov CHECK(REAL(__cxa_throw)); 354f54b1f9b73a6855d77ee270c282bd61407fa73a0Kostya Serebryany __asan_handle_no_return(); 35509672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(__cxa_throw)(a, b, c); 3564803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 3574803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany#endif 3584803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 35952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryanystatic inline int CharCmp(unsigned char c1, unsigned char c2) { 36052fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 36152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany} 36252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany 3633f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { 36486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 36586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, memcmp); 3662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (UNLIKELY(!asan_inited)) return internal_memcmp(a1, a2, size); 36752fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany ENSURE_ASAN_INITED(); 3681b057b20db71ec6cc2bac460c8b2848f0889d47dKostya Serebryany if (flags()->replace_intrin) { 3698bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko if (flags()->strict_memcmp) { 3708bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko // Check the entire regions even if the first bytes of the buffers are 3718bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko // different. 37286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, a1, size); 37386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, a2, size); 3748bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko // Fallthrough to REAL(memcmp) below. 3758bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko } else { 3768bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko unsigned char c1 = 0, c2 = 0; 3778bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko const unsigned char *s1 = (const unsigned char*)a1; 3788bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko const unsigned char *s2 = (const unsigned char*)a2; 3798bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko uptr i; 3808bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko for (i = 0; i < size; i++) { 3818bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko c1 = s1[i]; 3828bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko c2 = s2[i]; 3838bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko if (c1 != c2) break; 3848bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko } 38586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, s1, Min(i + 1, size)); 38686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, s2, Min(i + 1, size)); 3878bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko return CharCmp(c1, c2); 3888bd5e74fa9d37a182088114918380e255e22e493Alexander Potapenko } 38952fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany } 3901b057b20db71ec6cc2bac460c8b2848f0889d47dKostya Serebryany return REAL(memcmp(a1, a2, size)); 39152fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany} 39252fb238ccc45781e4e1d097ae1ee748c898b5825Kostya Serebryany 39386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// memcpy is called during __asan_init() from the internals of printf(...). 39486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// We do not treat memcpy with to==from as a bug. 39586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// See http://llvm.org/bugs/show_bug.cgi?id=11763. 39686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define ASAN_MEMCPY_IMPL(ctx, to, from, size) do { \ 39786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (UNLIKELY(!asan_inited)) return internal_memcpy(to, from, size); \ 39886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (asan_init_is_running) { \ 39986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return REAL(memcpy)(to, from, size); \ 40086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } \ 40186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ENSURE_ASAN_INITED(); \ 40286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (flags()->replace_intrin) { \ 40386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (to != from) { \ 40486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); \ 40586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } \ 40686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, from, size); \ 40786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_WRITE_RANGE(ctx, to, size); \ 40886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } \ 40986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return REAL(memcpy)(to, from, size); \ 41086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } while (0) 41186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 41286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 4132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *__asan_memcpy(void *to, const void *from, uptr size) { 41486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_MEMCPY_IMPL(nullptr, to, from, size); 4151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 41786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// memset is called inside Printf. 41886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define ASAN_MEMSET_IMPL(ctx, block, c, size) do { \ 41986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (UNLIKELY(!asan_inited)) return internal_memset(block, c, size); \ 42086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (asan_init_is_running) { \ 42186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return REAL(memset)(block, c, size); \ 42286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } \ 42386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ENSURE_ASAN_INITED(); \ 42486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (flags()->replace_intrin) { \ 42586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_WRITE_RANGE(ctx, block, size); \ 42686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } \ 42786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return REAL(memset)(block, c, size); \ 42886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } while (0) 42986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 4302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *__asan_memset(void *block, int c, uptr size) { 43186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_MEMSET_IMPL(nullptr, block, c, size); 4321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 43486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#define ASAN_MEMMOVE_IMPL(ctx, to, from, size) do { \ 43586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (UNLIKELY(!asan_inited)) \ 43686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return internal_memmove(to, from, size); \ 43786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ENSURE_ASAN_INITED(); \ 43886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (flags()->replace_intrin) { \ 43986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, from, size); \ 44086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_WRITE_RANGE(ctx, to, size); \ 44186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } \ 44286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return internal_memmove(to, from, size); \ 44386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } while (0) 44486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 4452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *__asan_memmove(void *to, const void *from, uptr size) { 44686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_MEMMOVE_IMPL(nullptr, to, from, size); 4472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 4482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 4492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) { 45086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 45186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, memmove); 45286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_MEMMOVE_IMPL(ctx, to, from, size); 4532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 4542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 4552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) { 45686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 45786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, memcpy); 4582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !SANITIZER_MAC 45986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_MEMCPY_IMPL(ctx, to, from, size); 4602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else 4612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // At least on 10.7 and 10.8 both memcpy() and memmove() are being replaced 4622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // with WRAP(memcpy). As a result, false positives are reported for memmove() 4632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // calls. If we just disable error reporting with 4642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // ASAN_OPTIONS=replace_intrin=0, memmove() is still replaced with 4652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // internal_memcpy(), which may lead to crashes, see 4662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // http://llvm.org/bugs/show_bug.cgi?id=16362. 46786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_MEMMOVE_IMPL(ctx, to, from, size); 4682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif // !SANITIZER_MAC 4692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 4702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 4712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesINTERCEPTOR(void*, memset, void *block, int c, uptr size) { 47286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 47386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, memset); 47486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_MEMSET_IMPL(ctx, block, c, size); 4752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 4762d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 477f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strchr, const char *str, int c) { 47886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 47986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, strchr); 4802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (UNLIKELY(!asan_inited)) return internal_strchr(str, c); 4818d6e3f7d011970e35dadf831964260bcf6a4d8a9Alexander Potapenko // strchr is called inside create_purgeable_zone() when MallocGuardEdges=1 is 4828d6e3f7d011970e35dadf831964260bcf6a4d8a9Alexander Potapenko // used. 4838d6e3f7d011970e35dadf831964260bcf6a4d8a9Alexander Potapenko if (asan_init_is_running) { 4848d6e3f7d011970e35dadf831964260bcf6a4d8a9Alexander Potapenko return REAL(strchr)(str, c); 4858d6e3f7d011970e35dadf831964260bcf6a4d8a9Alexander Potapenko } 486e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 48709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov char *result = REAL(strchr)(str, c); 488cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 489909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar uptr len = REAL(strlen)(str); 490909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar uptr bytes_read = (result ? result - str : len) + 1; 491909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar ASAN_READ_STRING_OF_LEN(ctx, str, len, bytes_read); 4921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 4931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return result; 4941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 496fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_INDEX 497fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov# if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 4984b0c5f240e71be4f375627e57d0f1b89600918a7Evgeniy StepanovINTERCEPTOR(char*, index, const char *string, int c) 49972bbfd4f3a442afde281476bc6bd41b3b2152a4eAlexander Potapenko ALIAS(WRAPPER_NAME(strchr)); 500fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov# else 50124e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov# if SANITIZER_MAC 50250a002ecad3f0a10c136496e5b6289bd3c71590eAlexander PotapenkoDECLARE_REAL(char*, index, const char *string, int c) 50350a002ecad3f0a10c136496e5b6289bd3c71590eAlexander PotapenkoOVERRIDE_FUNCTION(index, strchr); 50450a002ecad3f0a10c136496e5b6289bd3c71590eAlexander Potapenko# else 505fdde5a97a71b142297d7b2270c2a7f564a37dbaeAlexey SamsonovDEFINE_REAL(char*, index, const char *string, int c) 50650a002ecad3f0a10c136496e5b6289bd3c71590eAlexander Potapenko# endif 507fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov# endif 508fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif // ASAN_INTERCEPT_INDEX 509af0f01d77c2a495f023ffbf6cce85b33bbd2306dKostya Serebryany 51037b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko// For both strcat() and strncat() we need to check the validity of |to| 51137b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko// argument irrespective of the |from| length. 512f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT 51386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 51486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, strcat); // NOLINT 5150985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany ENSURE_ASAN_INITED(); 516cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 5173f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr from_length = REAL(strlen)(from); 51886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, from, from_length + 1); 51937b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko uptr to_length = REAL(strlen)(to); 520909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length); 52186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1); 52237b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko // If the copying actually happens, the |from| string should not overlap 52337b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko // with the resulting string starting at |to|, which has a length of 52437b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko // to_length + from_length + 1. 5250985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany if (from_length > 0) { 52637b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1, 52737b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko from, from_length + 1); 5280985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany } 5290985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany } 53009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strcat)(to, from); // NOLINT 5310985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany} 5320985ca240812ac5519168a6aecbccf4c513ae243Kostya Serebryany 533c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey SamsonovINTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) { 53486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 53586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, strncat); 536c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov ENSURE_ASAN_INITED(); 53737b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko if (flags()->replace_str) { 538c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov uptr from_length = MaybeRealStrnlen(from, size); 53937b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko uptr copy_length = Min(size, from_length + 1); 54086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, from, copy_length); 541c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov uptr to_length = REAL(strlen)(to); 542909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length); 54386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1); 544c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov if (from_length > 0) { 54537b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1, 54637b3fcd6fdec5740fe51fc1315c5d4d54313de98Alexander Potapenko from, copy_length); 547c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov } 548c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov } 549c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov return REAL(strncat)(to, from, size); 550c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov} 551c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov 552f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT 55386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 55486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, strcpy); // NOLINT 55524e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#if SANITIZER_MAC 5562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (UNLIKELY(!asan_inited)) return REAL(strcpy)(to, from); // NOLINT 5570ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#endif 5581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strcpy is called from malloc_default_purgeable_zone() 5591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 5601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 56109672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strcpy)(to, from); // NOLINT 5621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 563e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 564cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 5653f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr from_size = REAL(strlen)(from) + 1; 566c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size); 56786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, from, from_size); 56886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_WRITE_RANGE(ctx, to, from_size); 5691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 57009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strcpy)(to, from); // NOLINT 5711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 5721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 573fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_STRDUP 574f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(char*, strdup, const char *s) { 57586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 57686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, strdup); 5772d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (UNLIKELY(!asan_inited)) return internal_strdup(s); 578e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 579d530d892b4958a9ae54e57472d5d0a0bae1f6ad8Alexey Samsonov uptr length = REAL(strlen)(s); 580cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 58186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, s, length + 1); 5821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 583d530d892b4958a9ae54e57472d5d0a0bae1f6ad8Alexey Samsonov GET_STACK_TRACE_MALLOC; 584d530d892b4958a9ae54e57472d5d0a0bae1f6ad8Alexey Samsonov void *new_mem = asan_malloc(length + 1, &stack); 585d530d892b4958a9ae54e57472d5d0a0bae1f6ad8Alexey Samsonov REAL(memcpy)(new_mem, s, length + 1); 586d530d892b4958a9ae54e57472d5d0a0bae1f6ad8Alexey Samsonov return reinterpret_cast<char*>(new_mem); 5871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 588fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 5891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 5906d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERCEPTOR(SIZE_T, strlen, const char *s) { 59186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 59286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, strlen); 5932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (UNLIKELY(!asan_inited)) return internal_strlen(s); 5941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // strlen is called from malloc_default_purgeable_zone() 5951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // in __asan::ReplaceSystemAlloc() on Mac. 5961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (asan_init_is_running) { 59709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strlen)(s); 5981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 599e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 6006d1862363c88c183b0ed7740fca876342cf0474bStephen Hines SIZE_T length = REAL(strlen)(s); 601cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 60286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, s, length + 1); 6031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 6041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return length; 6051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 6061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 6076d1862363c88c183b0ed7740fca876342cf0474bStephen HinesINTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) { 60886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 60986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, wcslen); 6106d1862363c88c183b0ed7740fca876342cf0474bStephen Hines SIZE_T length = REAL(wcslen)(s); 611b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner if (!asan_init_is_running) { 612b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner ENSURE_ASAN_INITED(); 61386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, s, (length + 1) * sizeof(wchar_t)); 614b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner } 615b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner return length; 616b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner} 617b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner 6183f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) { 61986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 62086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, strncpy); 621e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 622cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 623c925697df6626bb0ea27ea96539bf0580f8f3d3dAlexey Samsonov uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1); 624c5e72a3b7c60f1b2d9d9be3a07d397d5b5f872beKostya Serebryany CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size); 62586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, from, from_size); 62686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_WRITE_RANGE(ctx, to, size); 6271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 62809672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(strncpy)(to, from, size); 6291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 6301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 63181a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#if ASAN_INTERCEPT_STRNLEN 6323f4c3875c42078e22c7e5356c5746fd18756d958Kostya SerebryanyINTERCEPTOR(uptr, strnlen, const char *s, uptr maxlen) { 63386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 63486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, strnlen); 635e130191a254064bfd1c8d373afdacf6d52979713Kostya Serebryany ENSURE_ASAN_INITED(); 6363f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany uptr length = REAL(strnlen)(s, maxlen); 637cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (flags()->replace_str) { 63886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_READ_RANGE(ctx, s, Min(length + 1, maxlen)); 6391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 6401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return length; 6411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 64281a7a4ab53c94e76c3b131d6f0ed82894640900bAlexey Samsonov#endif // ASAN_INTERCEPT_STRNLEN 643547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 644847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long, strtol, const char *nptr, // NOLINT 64584ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov char **endptr, int base) { 64686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 64786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, strtol); 64884ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov ENSURE_ASAN_INITED(); 649cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 650847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(strtol)(nptr, endptr, base); 65184ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov } 65284ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov char *real_endptr; 653847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT 654909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); 65584ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov return result; 65684ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov} 65784ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov 658847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(int, atoi, const char *nptr) { 65986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 66086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, atoi); 66124e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#if SANITIZER_MAC 6622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (UNLIKELY(!asan_inited)) return REAL(atoi)(nptr); 6630ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#endif 664847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ENSURE_ASAN_INITED(); 665cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 666847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(atoi)(nptr); 667847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov } 668847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov char *real_endptr; 669847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // "man atoi" tells that behavior of atoi(nptr) is the same as 6703f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the 671847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // parsed integer can't be stored in *long* type (even if it's 672847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov // different from int). So, we just imitate this behavior. 673847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov int result = REAL(strtol)(nptr, &real_endptr, 10); 674847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 675909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1); 676847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return result; 677847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov} 678847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov 679847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long, atol, const char *nptr) { // NOLINT 68086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 68186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, atol); 68224e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#if SANITIZER_MAC 6832d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (UNLIKELY(!asan_inited)) return REAL(atol)(nptr); 6840ef531054fc25c11e372cbab1384f10954984219Alexander Potapenko#endif 685847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ENSURE_ASAN_INITED(); 686cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 687847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(atol)(nptr); 688847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov } 689847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov char *real_endptr; 690847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT 691847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 692909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1); 693847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return result; 694847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov} 695847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov 696847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 697847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT 6988f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov char **endptr, int base) { 69986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 70086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, strtoll); 7018f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov ENSURE_ASAN_INITED(); 702cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 703847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(strtoll)(nptr, endptr, base); 7048f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov } 7058f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov char *real_endptr; 706847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT 707909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); 7088f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov return result; 7098f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov} 7108f6a77f3f59ebc5f40f235e51836f468f30b9110Alexey Samsonov 711847f932ab0405757946433b81d3b2952b306b0bcAlexey SamsonovINTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT 71286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines void *ctx; 71386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPTOR_ENTER(ctx, atoll); 714847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov ENSURE_ASAN_INITED(); 715cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov if (!flags()->replace_str) { 716847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return REAL(atoll)(nptr); 717847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov } 718847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov char *real_endptr; 719847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT 720847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov FixRealStrtolEndptr(nptr, &real_endptr); 721909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1); 722847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov return result; 723847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov} 724847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL 725847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov 72646efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonovstatic void AtCxaAtexit(void *unused) { 72746efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov (void)unused; 72846efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov StopInitOrderChecking(); 72946efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov} 73046efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov 73146efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov#if ASAN_INTERCEPT___CXA_ATEXIT 73246efcb09dc16b91cb805abea52f3ff6081a63751Alexey SamsonovINTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, 73346efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov void *dso_handle) { 734b527f7de80001569542e3f0ef4c7f4b0cb15cb67Alexander Potapenko#if SANITIZER_MAC 7352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (UNLIKELY(!asan_inited)) return REAL(__cxa_atexit)(func, arg, dso_handle); 736b527f7de80001569542e3f0ef4c7f4b0cb15cb67Alexander Potapenko#endif 73746efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov ENSURE_ASAN_INITED(); 73846efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov int res = REAL(__cxa_atexit)(func, arg, dso_handle); 73946efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov REAL(__cxa_atexit)(AtCxaAtexit, 0, 0); 74046efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov return res; 74146efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov} 74246efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov#endif // ASAN_INTERCEPT___CXA_ATEXIT 74346efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov 7446a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if ASAN_INTERCEPT_FORK 7456a211c5814e25d6745a5058cc0e499e5235d3821Stephen HinesINTERCEPTOR(int, fork, void) { 7466a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENSURE_ASAN_INITED(); 7476a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines if (common_flags()->coverage) CovBeforeFork(); 7486a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines int pid = REAL(fork)(); 7496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines if (common_flags()->coverage) CovAfterFork(pid); 7506a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines return pid; 7516a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines} 7526a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif // ASAN_INTERCEPT_FORK 7536a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines 754547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany// ---------------------- InitializeAsanInterceptors ---------------- {{{1 755547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanynamespace __asan { 756547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryanyvoid InitializeAsanInterceptors() { 757fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany static bool was_called_once; 758fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany CHECK(was_called_once == false); 759fdbdab5ff8de4c23b58bb411ea2358a78e2d9b2fKostya Serebryany was_called_once = true; 7602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines InitializeCommonInterceptors(); 7618530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany 76207bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intercept mem* functions. 763580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memcmp); 764580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memmove); 765580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memset); 76638dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { 767580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(memcpy); 768573fb4b102dda9d231a8dbd0c01e67e84e9b0874Alexander Potapenko } 76907bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov 77007bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intercept str* functions. 771580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strcat); // NOLINT 772580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strchr); 773580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strcpy); // NOLINT 774580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strlen); 775b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner ASAN_INTERCEPT_FUNC(wcslen); 776c1bdd5adca453f2fae238a4c53ade35ae60b85daAlexey Samsonov ASAN_INTERCEPT_FUNC(strncat); 777580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strncpy); 778fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_STRDUP 779fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov ASAN_INTERCEPT_FUNC(strdup); 780fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 781fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_STRNLEN 782fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov ASAN_INTERCEPT_FUNC(strnlen); 783fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 78469563986ca570ce750111a82264d51ddbf4107baAlexander Potapenko#if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 785580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(index); 78607bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif 7875b29018cf422e7711fb760b733c32127397a43fcAlexey Samsonov 788580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(atoi); 789580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(atol); 790580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strtol); 791847f932ab0405757946433b81d3b2952b306b0bcAlexey Samsonov#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 792580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(atoll); 793580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(strtoll); 79484ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov#endif 79584ba324b94d22a69acc823e845f9718fd2984e44Alexey Samsonov 79607bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intecept signal- and jump-related functions. 797580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(longjmp); 79834a3202a2c22816a6da66959e266a2d078ded37bAlexey Samsonov#if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 799580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(sigaction); 8002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_ANDROID 8012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines ASAN_INTERCEPT_FUNC(bsd_signal); 8022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else 803580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(signal); 804919c24787a655597bdcf367e26c9dd1504e9f463Evgeniy Stepanov#endif 8052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 8060870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov#if ASAN_INTERCEPT_SWAPCONTEXT 8070870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov ASAN_INTERCEPT_FUNC(swapcontext); 8080870028410087e67a0049c76cb7c64f02c260d24Alexey Samsonov#endif 809fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT__LONGJMP 810580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(_longjmp); 811fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 812fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_SIGLONGJMP 813580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(siglongjmp); 814fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#endif 815fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov 816fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov // Intercept exception handling functions. 817fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT___CXA_THROW 8186d1862363c88c183b0ed7740fca876342cf0474bStephen Hines ASAN_INTERCEPT_FUNC(__cxa_throw); 8193e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov#endif 8203e81fe43798c096d1d3565596f0717b9919de4fbTimur Iskhodzhanov 82107bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov // Intercept threading-related functions 822fd2ae4fc7df0e5acd200f30d87bbc6b96830a989Alexey Samsonov#if ASAN_INTERCEPT_PTHREAD_CREATE 823580469d7e40e39319cb2d3750edac4bccca18105Dmitry Vyukov ASAN_INTERCEPT_FUNC(pthread_create); 82486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines ASAN_INTERCEPT_FUNC(pthread_join); 82507bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov#endif 82607bb9f1e3600195119aec1aae1aa48a6ed2f5febTimur Iskhodzhanov 82746efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov // Intercept atexit function. 82846efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov#if ASAN_INTERCEPT___CXA_ATEXIT 82946efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov ASAN_INTERCEPT_FUNC(__cxa_atexit); 83046efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov#endif 83146efcb09dc16b91cb805abea52f3ff6081a63751Alexey Samsonov 8326a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#if ASAN_INTERCEPT_FORK 8336a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ASAN_INTERCEPT_FUNC(fork); 8346a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#endif 8356a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines 8367c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar InitializePlatformInterceptors(); 837600972e3427173cc8904d741decd1af0ed5de9fdTimur Iskhodzhanov 8382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "AddressSanitizer: libc interceptors initialized\n"); 839547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany} 840547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany 841547652c45fd7f7497dd214ec8ec6b6ee0f80359dKostya Serebryany} // namespace __asan 842