asan_rtl.cc revision 09672caefb5694f1981a1712fdefa44840a95e67
1ad5e73887052193afda72db8efcb812bd083a4a8John McCall//===-- asan_rtl.cc ---------------------------------------------*- C++ -*-===// 25f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor// 35f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor// The LLVM Compiler Infrastructure 4b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson// 59234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson// This file is distributed under the University of Illinois Open Source 69234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson// License. See LICENSE.TXT for details. 79234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson// 89234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson//===----------------------------------------------------------------------===// 99234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson// 109234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson// This file is a part of AddressSanitizer, an address sanity checker. 1131455256ae26cc7069111643ec4429ea564377daSean Hunt// 1231455256ae26cc7069111643ec4429ea564377daSean Hunt// Main file of the ASan run-time library. 1331455256ae26cc7069111643ec4429ea564377daSean Hunt//===----------------------------------------------------------------------===// 149234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson#include "asan_allocator.h" 155f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor#include "asan_interceptors.h" 165f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor#include "asan_interface.h" 179234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson#include "asan_internal.h" 18b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "asan_lock.h" 19b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "asan_mapping.h" 20b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "asan_procmaps.h" 219234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson#include "asan_stack.h" 22b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "asan_stats.h" 23b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "asan_thread.h" 24b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson#include "asan_thread_registry.h" 259234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson 26b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlssonnamespace __asan { 27b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson 284843e584b54460973b8445d38907bab0401ebb0cAnders Carlsson// -------------------------- Flags ------------------------- {{{1 299234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlssonstatic const size_t kMallocContextSize = 30; 304843e584b54460973b8445d38907bab0401ebb0cAnders Carlssonstatic int FLAG_atexit; 314843e584b54460973b8445d38907bab0401ebb0cAnders Carlsson 324843e584b54460973b8445d38907bab0401ebb0cAnders Carlssonsize_t FLAG_redzone; // power of two, >= 32 339234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlssonsize_t FLAG_quarantine_size; 34c6c91bc019ff7fa09f6570025ba011aad4c0d004Anders Carlssonint FLAG_demangle; 35984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlssonbool FLAG_symbolize; 369234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlssonint FLAG_v; 37984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlssonint FLAG_debug; 38984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlssonbool FLAG_poison_shadow; 399234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlssonint FLAG_report_globals; 40984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlssonsize_t FLAG_malloc_context_size = kMallocContextSize; 4191e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlssonuintptr_t FLAG_large_malloc; 429234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlssonbool FLAG_handle_segv; 4391e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlssonbool FLAG_replace_str; 4491e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlssonbool FLAG_replace_intrin; 452928c2107f2e0007f35fe1c224aab63535f1403dAnders Carlssonbool FLAG_replace_cfallocator; // Used on Mac only. 4691e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlssonsize_t FLAG_max_malloc_fill_size = 0; 47329749c1ec1ead3c41af52260f1203e4991b4e83Anders Carlssonbool FLAG_use_fake_stack; 481b42c794481f6f958267e4ba913d74fef43161f6Anders Carlssonint FLAG_exitcode = EXIT_FAILURE; 491b42c794481f6f958267e4ba913d74fef43161f6Anders Carlssonbool FLAG_allow_user_poisoning; 50283a062a633d6e868aa2be319da812341fe73728Anders Carlssonint FLAG_sleep_before_dying; 51283a062a633d6e868aa2be319da812341fe73728Anders Carlsson 522df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner// -------------------------- Globals --------------------- {{{1 539234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlssonint asan_inited; 542df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattnerbool asan_init_is_running; 557a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson 567a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson// -------------------------- Misc ---------------- {{{1 577a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlssonvoid ShowStatsAndAbort() { 589234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson __asan_print_accumulated_stats(); 597a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson AsanDie(); 607a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson} 619234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson 627a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlssonstatic void PrintBytes(const char *before, uintptr_t *a) { 637a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson uint8_t *bytes = (uint8_t*)a; 647a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson size_t byte_num = (__WORDSIZE) / 8; 659234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson Printf("%s%p:", before, (uintptr_t)a); 667a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson for (size_t i = 0; i < byte_num; i++) { 677a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson Printf(" %lx%lx", bytes[i] >> 4, bytes[i] & 15); 689234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson } 697a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson Printf("\n"); 707a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson} 717a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson 727a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlssonsize_t ReadFileToBuffer(const char *file_name, char **buff, 739234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson size_t *buff_size, size_t max_len) { 747a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson const size_t kMinFileLen = kPageSize; 757a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson size_t read_len = 0; 769234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson *buff = 0; 777a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson *buff_size = 0; 787a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson // The files we usually open are not seekable, so try different buffer sizes. 799234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson for (size_t size = kMinFileLen; size <= max_len; size *= 2) { 807a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson int fd = AsanOpenReadonly(file_name); 810e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson if (fd < 0) return -1; 820e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson AsanUnmapOrDie(*buff, *buff_size); 830e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson *buff = (char*)AsanMmapSomewhereOrDie(size, __FUNCTION__); 849234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson *buff_size = size; 850e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson // Read up to one page at a time. 860e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson read_len = 0; 879234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson bool reached_eof = false; 880e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson while (read_len + kPageSize <= size) { 89cf85b933fef4ce827df83ef2d22c322ab2078aa5Anders Carlsson size_t just_read = AsanRead(fd, *buff + read_len, kPageSize); 909234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson if (just_read == 0) { 91cf85b933fef4ce827df83ef2d22c322ab2078aa5Anders Carlsson reached_eof = true; 92cf85b933fef4ce827df83ef2d22c322ab2078aa5Anders Carlsson break; 9303c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson } 9403c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson read_len += just_read; 9503c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson } 969234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson AsanClose(fd); 977624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson if (reached_eof) // We've read the whole file. 987624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson break; 997624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson } 1007482e247163978792654ca1a99913e19dd507e0aAnders Carlsson return read_len; 1017482e247163978792654ca1a99913e19dd507e0aAnders Carlsson} 1027624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson 1037624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson// ---------------------- mmap -------------------- {{{1 104d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlssonvoid OutOfMemoryMessageAndDie(const char *mem_type, size_t size) { 10503c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson Report("ERROR: AddressSanitizer failed to allocate " 10603c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson "0x%lx (%ld) bytes of %s\n", 10703c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson size, size, mem_type); 10803c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson PRINT_CURRENT_STACK(); 10903c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson ShowStatsAndAbort(); 1107624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson} 1117624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson 1127624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson// Reserve memory range [beg, end]. 1137482e247163978792654ca1a99913e19dd507e0aAnders Carlssonstatic void ReserveShadowMemoryRange(uintptr_t beg, uintptr_t end) { 1147482e247163978792654ca1a99913e19dd507e0aAnders Carlsson CHECK((beg % kPageSize) == 0); 1157482e247163978792654ca1a99913e19dd507e0aAnders Carlsson CHECK(((end + 1) % kPageSize) == 0); 1167482e247163978792654ca1a99913e19dd507e0aAnders Carlsson size_t size = end - beg + 1; 1177482e247163978792654ca1a99913e19dd507e0aAnders Carlsson void *res = AsanMmapFixedNoReserve(beg, size); 118d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson CHECK(res == (void*)beg && "ReserveShadowMemoryRange failed"); 119d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson} 120d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson 121d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson// ---------------------- LowLevelAllocator ------------- {{{1 122d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlssonvoid *LowLevelAllocator::Allocate(size_t size) { 123d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson CHECK((size & (size - 1)) == 0 && "size must be a power of two"); 124d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson if (allocated_end_ - allocated_current_ < size) { 125d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson size_t size_to_allocate = Max(size, kPageSize); 126d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson allocated_current_ = 127d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson (char*)AsanMmapSomewhereOrDie(size_to_allocate, __FUNCTION__); 128d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson allocated_end_ = allocated_current_ + size_to_allocate; 129d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson PoisonShadow((uintptr_t)allocated_current_, size_to_allocate, 1307482e247163978792654ca1a99913e19dd507e0aAnders Carlsson kAsanInternalHeapMagic); 1317482e247163978792654ca1a99913e19dd507e0aAnders Carlsson } 1327482e247163978792654ca1a99913e19dd507e0aAnders Carlsson CHECK(allocated_end_ - allocated_current_ >= size); 133d58d6f778de936516d8815783f2e88348c41dce4Anders Carlsson void *res = allocated_current_; 1347482e247163978792654ca1a99913e19dd507e0aAnders Carlsson allocated_current_ += size; 1355cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson return res; 1365cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson} 1375cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson 1385cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson// ---------------------- DescribeAddress -------------------- {{{1 1395cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlssonstatic bool DescribeStackAddress(uintptr_t addr, uintptr_t access_size) { 1405cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson AsanThread *t = asanThreadRegistry().FindThreadByStackAddress(addr); 1415cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson if (!t) return false; 142add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson const intptr_t kBufSize = 4095; 143add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson char buf[kBufSize]; 144add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson uintptr_t offset = 0; 145add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson const char *frame_descr = t->GetFrameNameByAddr(addr, &offset); 1468257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson // This string is created by the compiler and has the following form: 147add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson // "FunctioName n alloc_1 alloc_2 ... alloc_n" 148add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson // where alloc_i looks like "offset size len ObjectName ". 149add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson CHECK(frame_descr); 150add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson // Report the function name and the offset. 151add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson const char *name_end = REAL(strchr)(frame_descr, ' '); 152ae3524866124021f3bc695886668254093c0793fAnders Carlsson CHECK(name_end); 153ae3524866124021f3bc695886668254093c0793fAnders Carlsson buf[0] = 0; 154ae3524866124021f3bc695886668254093c0793fAnders Carlsson internal_strncat(buf, frame_descr, 155ae3524866124021f3bc695886668254093c0793fAnders Carlsson Min(kBufSize, 156ae3524866124021f3bc695886668254093c0793fAnders Carlsson static_cast<intptr_t>(name_end - frame_descr))); 157ae3524866124021f3bc695886668254093c0793fAnders Carlsson Printf("Address %p is located at offset %ld " 158ae3524866124021f3bc695886668254093c0793fAnders Carlsson "in frame <%s> of T%d's stack:\n", 159ae3524866124021f3bc695886668254093c0793fAnders Carlsson addr, offset, buf, t->tid()); 1601668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson // Report the number of stack objects. 1611668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson char *p; 1621668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson size_t n_objects = strtol(name_end, &p, 10); 1631668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson CHECK(n_objects > 0); 1641668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson Printf(" This frame has %ld object(s):\n", n_objects); 1651668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson // Report all objects in this frame. 1661668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson for (size_t i = 0; i < n_objects; i++) { 167aeb85374e92619b8e4ce92ac6e30756b5053a137Anders Carlsson size_t beg, size; 1681668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson intptr_t len; 1691668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson beg = strtol(p, &p, 10); 1701668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson size = strtol(p, &p, 10); 1711668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson len = strtol(p, &p, 10); 1721668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson if (beg <= 0 || size <= 0 || len < 0 || *p != ' ') { 1731668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson Printf("AddressSanitizer can't parse the stack frame descriptor: |%s|\n", 1741668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson frame_descr); 1751668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson break; 1761668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson } 1770ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson p++; 1780ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson buf[0] = 0; 1790ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson internal_strncat(buf, p, Min(kBufSize, len)); 1800ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson p += len; 1810ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson Printf(" [%ld, %ld) '%s'\n", beg, beg + size, buf); 1820ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson } 1830ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson Printf("HINT: this may be a false positive if your program uses " 1840ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson "some custom stack unwind mechanism\n" 18550755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson " (longjmp and C++ exceptions *are* supported)\n"); 18650755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson t->summary()->Announce(); 18750755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson return true; 18850755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson} 18950755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson 19050755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlssonstatic NOINLINE void DescribeAddress(uintptr_t addr, uintptr_t access_size) { 19150755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson // Check if this is a global. 19250755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson if (DescribeAddrIfGlobal(addr)) 19350755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson return; 19450755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson 19550755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson if (DescribeStackAddress(addr, access_size)) 19650755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson return; 19750755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson 19850755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson // finally, check if this is a heap. 19950755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson DescribeHeapAddress(addr, access_size); 20050755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson} 20150755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson 20250755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson// -------------------------- Run-time entry ------------------- {{{1 203b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson// exported functions 204b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson#define ASAN_REPORT_ERROR(type, is_write, size) \ 205b217c1b9d2225521f4021984ad5a424784fa22bbAnders CarlssonNOINLINE ASAN_INTERFACE_ATTRIBUTE \ 206b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlssonextern "C" void __asan_report_ ## type ## size(uintptr_t addr); \ 207b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlssonextern "C" void __asan_report_ ## type ## size(uintptr_t addr) { \ 208b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson GET_BP_PC_SP; \ 209b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson __asan_report_error(pc, bp, sp, addr, is_write, size); \ 210b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson} 211b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson 212c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(load, false, 1) 2135c478cf2d54157062cd843737324e0d0df03a464Anders CarlssonASAN_REPORT_ERROR(load, false, 2) 214c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(load, false, 4) 2155c478cf2d54157062cd843737324e0d0df03a464Anders CarlssonASAN_REPORT_ERROR(load, false, 8) 216c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(load, false, 16) 217c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(store, true, 1) 218c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(store, true, 2) 219c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(store, true, 4) 220c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(store, true, 8) 221c4355b6883382b85cda3b7337587784dabf3450bAnders CarlssonASAN_REPORT_ERROR(store, true, 16) 2228e51a1f5da6ef4a1a168d14116c6eed3a578a263John McCall 223c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson// Force the linker to keep the symbols for various ASan interface functions. 224c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson// We want to keep those in the executable in order to let the instrumented 225c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson// dynamic libraries access the symbol even if it is not used by the executable 226c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson// itself. This should help if the build system is removing dead code at link 227a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson// time. 228a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlssonstatic void force_interface_symbols() { 229a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson volatile int fake_condition = 0; // prevent dead condition elimination. 230a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson if (fake_condition) { 231a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson __asan_report_load1(NULL); 232a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson __asan_report_load2(NULL); 233e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson __asan_report_load4(NULL); 23458040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson __asan_report_load8(NULL); 23558040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson __asan_report_load16(NULL); 23658040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson __asan_report_store1(NULL); 23758040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson __asan_report_store2(NULL); 23858040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson __asan_report_store4(NULL); 23958040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson __asan_report_store8(NULL); 24058040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson __asan_report_store16(NULL); 24158040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson __asan_register_global(0, 0, NULL); 24258040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson __asan_register_globals(NULL, 0); 24358040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson __asan_unregister_globals(NULL, 0); 24458040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson } 24558040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson} 24658040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson 24758040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson// -------------------------- Init ------------------- {{{1 24858040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson#if defined(_WIN32) 24958040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson// atoll is not defined on Windows. 250e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlssonint64_t atoll(const char *str) { 251e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson UNIMPLEMENTED(); 252e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson return -1; 2538f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor} 254e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson#endif 255e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson 256e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlssonstatic int64_t IntFlagValue(const char *flags, const char *flag, 2578f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor int64_t default_val) { 258e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson if (!flags) return default_val; 259e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson const char *str = internal_strstr(flags, flag); 260e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson if (!str) return default_val; 261e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson return atoll(str + internal_strlen(flag)); 262e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson} 2638f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor 264e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlssonstatic void asan_atexit() { 265e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson Printf("AddressSanitizer exit stats:\n"); 266e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson __asan_print_accumulated_stats(); 2678f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor} 268e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson 269e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlssonvoid CheckFailed(const char *cond, const char *file, int line) { 270e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson Report("CHECK failed: %s at %s:%d\n", cond, file, line); 271e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson PRINT_CURRENT_STACK(); 2728f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor ShowStatsAndAbort(); 273e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson} 274e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson 275e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson} // namespace __asan 2768257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson 2778257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson// ---------------------- Interface ---------------- {{{1 2788257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlssonusing namespace __asan; // NOLINT 2798257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson 2808257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlssonint __asan_set_error_exit_code(int exit_code) { 2818257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson int old = FLAG_exitcode; 2828257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson FLAG_exitcode = exit_code; 2838257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson return old; 2848257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson} 2858257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson 2868257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlssonvoid __asan_report_error(uintptr_t pc, uintptr_t bp, uintptr_t sp, 2878257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson uintptr_t addr, bool is_write, size_t access_size) { 2888257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson // Do not print more than one report, otherwise they will mix up. 2898257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson static int num_calls = 0; 2908257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson if (AtomicInc(&num_calls) > 1) return; 2918257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson 2928257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson Printf("=================================================================\n"); 2938257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson const char *bug_descr = "unknown-crash"; 2948257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson if (AddrIsInMem(addr)) { 2959e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson uint8_t *shadow_addr = (uint8_t*)MemToShadow(addr); 2969e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson // If we are accessing 16 bytes, look at the second shadow byte. 2979e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson if (*shadow_addr == 0 && access_size > SHADOW_GRANULARITY) 2989e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson shadow_addr++; 2999e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson // If we are in the partial right redzone, look at the next shadow byte. 3009e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson if (*shadow_addr > 0 && *shadow_addr < 128) 3019e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson shadow_addr++; 3029e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson switch (*shadow_addr) { 3039e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson case kAsanHeapLeftRedzoneMagic: 3049e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson case kAsanHeapRightRedzoneMagic: 3059e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson bug_descr = "heap-buffer-overflow"; 3069e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson break; 3079e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson case kAsanHeapFreeMagic: 3088f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor bug_descr = "heap-use-after-free"; 3099e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson break; 3109e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson case kAsanStackLeftRedzoneMagic: 311f28c687866aed1ed7b4b9ddf44a51673861236cfAnders Carlsson bug_descr = "stack-buffer-underflow"; 312f28c687866aed1ed7b4b9ddf44a51673861236cfAnders Carlsson break; 313a9efbf009468f36df0bb66551677339055757d51Nuno Lopes case kAsanStackMidRedzoneMagic: 314a9efbf009468f36df0bb66551677339055757d51Nuno Lopes case kAsanStackRightRedzoneMagic: 31531455256ae26cc7069111643ec4429ea564377daSean Hunt case kAsanStackPartialRedzoneMagic: 31631455256ae26cc7069111643ec4429ea564377daSean Hunt bug_descr = "stack-buffer-overflow"; 31731455256ae26cc7069111643ec4429ea564377daSean Hunt break; 31831455256ae26cc7069111643ec4429ea564377daSean Hunt case kAsanStackAfterReturnMagic: 31931455256ae26cc7069111643ec4429ea564377daSean Hunt bug_descr = "stack-use-after-return"; 32031455256ae26cc7069111643ec4429ea564377daSean Hunt break; 32131455256ae26cc7069111643ec4429ea564377daSean Hunt case kAsanUserPoisonedMemoryMagic: 32231455256ae26cc7069111643ec4429ea564377daSean Hunt bug_descr = "use-after-poison"; 32331455256ae26cc7069111643ec4429ea564377daSean Hunt break; 32431455256ae26cc7069111643ec4429ea564377daSean Hunt case kAsanGlobalRedzoneMagic: 3251dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall bug_descr = "global-buffer-overflow"; 3261dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall break; 3271dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall } 3281dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall } 3291dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall 3301dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall AsanThread *curr_thread = asanThreadRegistry().GetCurrent(); 3311dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall int curr_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); 3321dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall 3331dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall if (curr_thread) { 3341dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall // We started reporting an error message. Stop using the fake stack 3351dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall // in case we will call an instrumented function from a symbolizer. 3361dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall curr_thread->fake_stack().StopUsingFakeStack(); 3371dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall } 3381dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall 3391dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall Report("ERROR: AddressSanitizer %s on address " 3401dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall "%p at pc 0x%lx bp 0x%lx sp 0x%lx\n", 3411dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall bug_descr, addr, pc, bp, sp); 3421dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall 3431dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall Printf("%s of size %d at %p thread T%d\n", 3441dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", 3451dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall access_size, addr, curr_tid); 3461dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall 3471dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall if (FLAG_debug) { 3481dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall PrintBytes("PC: ", (uintptr_t*)pc); 3491dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall } 3501dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall 3511dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp); 3521dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall stack.PrintStack(); 3531dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall 3541dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall CHECK(AddrIsInMem(addr)); 3551dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall 3561dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall DescribeAddress(addr, access_size); 3571dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall 3581dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall uintptr_t shadow_addr = MemToShadow(addr); 3592f27bf854f0519810b34afd209089cc75536b757John McCall Report("ABORTING\n"); 3602f27bf854f0519810b34afd209089cc75536b757John McCall __asan_print_accumulated_stats(); 3612f27bf854f0519810b34afd209089cc75536b757John McCall Printf("Shadow byte and word:\n"); 3622f27bf854f0519810b34afd209089cc75536b757John McCall Printf(" %p: %x\n", shadow_addr, *(unsigned char*)shadow_addr); 3632f27bf854f0519810b34afd209089cc75536b757John McCall uintptr_t aligned_shadow = shadow_addr & ~(kWordSize - 1); 3642f27bf854f0519810b34afd209089cc75536b757John McCall PrintBytes(" ", (uintptr_t*)(aligned_shadow)); 3652f27bf854f0519810b34afd209089cc75536b757John McCall Printf("More shadow bytes:\n"); 366e1e342f4a96f132d8d7e802284417bd520f9f4f8John McCall PrintBytes(" ", (uintptr_t*)(aligned_shadow-4*kWordSize)); 3671dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall PrintBytes(" ", (uintptr_t*)(aligned_shadow-3*kWordSize)); 36832fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor PrintBytes(" ", (uintptr_t*)(aligned_shadow-2*kWordSize)); 36932fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor PrintBytes(" ", (uintptr_t*)(aligned_shadow-1*kWordSize)); 37032fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor PrintBytes("=>", (uintptr_t*)(aligned_shadow+0*kWordSize)); 37132fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor PrintBytes(" ", (uintptr_t*)(aligned_shadow+1*kWordSize)); 3728f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor PrintBytes(" ", (uintptr_t*)(aligned_shadow+2*kWordSize)); 37332fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor PrintBytes(" ", (uintptr_t*)(aligned_shadow+3*kWordSize)); 37432fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor PrintBytes(" ", (uintptr_t*)(aligned_shadow+4*kWordSize)); 375aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlsson AsanDie(); 376aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlsson} 377aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlsson 378aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlssonvoid __asan_init() { 379ad5e73887052193afda72db8efcb812bd083a4a8John McCall if (asan_inited) return; 380ad5e73887052193afda72db8efcb812bd083a4a8John McCall asan_init_is_running = true; 381ad5e73887052193afda72db8efcb812bd083a4a8John McCall 382ad5e73887052193afda72db8efcb812bd083a4a8John McCall // Make sure we are not statically linked. 383ad5e73887052193afda72db8efcb812bd083a4a8John McCall AsanDoesNotSupportStaticLinkage(); 384ad5e73887052193afda72db8efcb812bd083a4a8John McCall 385ad5e73887052193afda72db8efcb812bd083a4a8John McCall // flags 386ad5e73887052193afda72db8efcb812bd083a4a8John McCall const char *options = AsanGetEnv("ASAN_OPTIONS"); 387ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_malloc_context_size = 388ad5e73887052193afda72db8efcb812bd083a4a8John McCall IntFlagValue(options, "malloc_context_size=", kMallocContextSize); 389ad5e73887052193afda72db8efcb812bd083a4a8John McCall CHECK(FLAG_malloc_context_size <= kMallocContextSize); 390ad5e73887052193afda72db8efcb812bd083a4a8John McCall 391ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_max_malloc_fill_size = 392ad5e73887052193afda72db8efcb812bd083a4a8John McCall IntFlagValue(options, "max_malloc_fill_size=", 0); 393ad5e73887052193afda72db8efcb812bd083a4a8John McCall 394ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_v = IntFlagValue(options, "verbosity=", 0); 395ad5e73887052193afda72db8efcb812bd083a4a8John McCall 396ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_redzone = IntFlagValue(options, "redzone=", 128); 397ad5e73887052193afda72db8efcb812bd083a4a8John McCall CHECK(FLAG_redzone >= 32); 398ad5e73887052193afda72db8efcb812bd083a4a8John McCall CHECK((FLAG_redzone & (FLAG_redzone - 1)) == 0); 399ad5e73887052193afda72db8efcb812bd083a4a8John McCall 400ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_atexit = IntFlagValue(options, "atexit=", 0); 401ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_poison_shadow = IntFlagValue(options, "poison_shadow=", 1); 4028f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor FLAG_report_globals = IntFlagValue(options, "report_globals=", 1); 403ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_handle_segv = IntFlagValue(options, "handle_segv=", ASAN_NEEDS_SEGV); 404ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_symbolize = IntFlagValue(options, "symbolize=", 1); 4058f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor FLAG_demangle = IntFlagValue(options, "demangle=", 1); 406ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_debug = IntFlagValue(options, "debug=", 0); 407ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_replace_cfallocator = IntFlagValue(options, "replace_cfallocator=", 1); 408ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_replace_str = IntFlagValue(options, "replace_str=", 1); 409ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_replace_intrin = IntFlagValue(options, "replace_intrin=", 1); 410ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_use_fake_stack = IntFlagValue(options, "use_fake_stack=", 1); 411ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_exitcode = IntFlagValue(options, "exitcode=", EXIT_FAILURE); 412ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_allow_user_poisoning = IntFlagValue(options, 413ad5e73887052193afda72db8efcb812bd083a4a8John McCall "allow_user_poisoning=", 1); 414ad5e73887052193afda72db8efcb812bd083a4a8John McCall FLAG_sleep_before_dying = IntFlagValue(options, "sleep_before_dying=", 0); 415ad5e73887052193afda72db8efcb812bd083a4a8John McCall 416ad5e73887052193afda72db8efcb812bd083a4a8John McCall if (FLAG_atexit) { 417d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola atexit(asan_atexit); 418d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola } 419d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola 420d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola FLAG_quarantine_size = 421d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola IntFlagValue(options, "quarantine_size=", 1UL << 28); 422d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola 423d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola // interceptors 424d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola InitializeAsanInterceptors(); 425d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola 426d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola ReplaceSystemMalloc(); 427d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola InstallSignalHandlers(); 428d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola 429d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola if (FLAG_v) { 430d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola Printf("|| `[%p, %p]` || HighMem ||\n", kHighMemBeg, kHighMemEnd); 431d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola Printf("|| `[%p, %p]` || HighShadow ||\n", 432d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola kHighShadowBeg, kHighShadowEnd); 433d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola Printf("|| `[%p, %p]` || ShadowGap ||\n", 434d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola kShadowGapBeg, kShadowGapEnd); 435d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola Printf("|| `[%p, %p]` || LowShadow ||\n", 436d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola kLowShadowBeg, kLowShadowEnd); 437d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola Printf("|| `[%p, %p]` || LowMem ||\n", kLowMemBeg, kLowMemEnd); 438d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola Printf("MemToShadow(shadow): %p %p %p %p\n", 439d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola MEM_TO_SHADOW(kLowShadowBeg), 440d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola MEM_TO_SHADOW(kLowShadowEnd), 441d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola MEM_TO_SHADOW(kHighShadowBeg), 442d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola MEM_TO_SHADOW(kHighShadowEnd)); 443d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola Printf("red_zone=%ld\n", FLAG_redzone); 444d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola Printf("malloc_context_size=%ld\n", (int)FLAG_malloc_context_size); 445d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola 446d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola Printf("SHADOW_SCALE: %lx\n", SHADOW_SCALE); 447d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola Printf("SHADOW_GRANULARITY: %lx\n", SHADOW_GRANULARITY); 448d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola Printf("SHADOW_OFFSET: %lx\n", SHADOW_OFFSET); 449d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7); 4508f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor } 451d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola 452d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola if (__WORDSIZE == 64) { 4537002f4c03c2d0544f4e8bea8d3a5636519081e35John McCall // Disable core dumper -- it makes little sense to dump 16T+ core. 454d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola AsanDisableCoreDumper(); 455d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola } 4569b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola 4579b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola { 4589b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola if (kLowShadowBeg != kLowShadowEnd) { 4599b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola // mmap the low shadow plus one page. 4609b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola ReserveShadowMemoryRange(kLowShadowBeg - kPageSize, kLowShadowEnd); 4619b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola } 4629b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola // mmap the high shadow. 4639b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd); 4649b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola // protect the gap 4659b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola void *prot = AsanMprotect(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); 4669b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola CHECK(prot == (void*)kShadowGapBeg); 4679b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola } 4689b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola 4699b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited 4709b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola // should be set to 1 prior to initializing the threads. 471 asan_inited = 1; 472 asan_init_is_running = false; 473 474 asanThreadRegistry().Init(); 475 asanThreadRegistry().GetMain()->ThreadStart(); 476 force_interface_symbols(); // no-op. 477 478 if (FLAG_v) { 479 Report("AddressSanitizer Init done\n"); 480 } 481} 482 483#if defined(ASAN_USE_PREINIT_ARRAY) 484// On Linux, we force __asan_init to be called before anyone else 485// by placing it into .preinit_array section. 486// FIXME: do we have anything like this on Mac? 487__attribute__((section(".preinit_array"))) 488 typeof(__asan_init) *__asan_preinit =__asan_init; 489#endif 490