asan_posix.cc revision b823e3c5f7891dbbde1eb288237f5f3d5ed64d85
1a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany//===-- asan_linux.cc -----------------------------------------------------===// 2a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// 3a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// The LLVM Compiler Infrastructure 4a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// 5a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// This file is distributed under the University of Illinois Open Source 6a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// License. See LICENSE.TXT for details. 7a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// 8a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany//===----------------------------------------------------------------------===// 9a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// 10a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 11a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// 12a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany// Posix-specific details. 13a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany//===----------------------------------------------------------------------===// 14a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#if defined(__linux__) || defined(__APPLE__) 15a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 16a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#include "asan_internal.h" 17a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#include "asan_interceptors.h" 1899d17ebc36fe74326493bdd3dab4082ffc1dc96eAlexander Potapenko#include "asan_procmaps.h" 19a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#include "asan_stack.h" 20a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#include "asan_thread_registry.h" 21a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 22cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany#include <pthread.h> 23a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#include <signal.h> 24b823e3c5f7891dbbde1eb288237f5f3d5ed64d85Alexey Samsonov#include <stdlib.h> 25a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#include <sys/time.h> 26a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#include <sys/resource.h> 270ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryany#include <unistd.h> 28a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 29dde7c33df06a9a0a8056f2357d764a10512206eeKostya Serebryany#ifdef ANDROID 30dde7c33df06a9a0a8056f2357d764a10512206eeKostya Serebryany#include <sys/atomics.h> 31dde7c33df06a9a0a8056f2357d764a10512206eeKostya Serebryany#endif 32dde7c33df06a9a0a8056f2357d764a10512206eeKostya Serebryany 33a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryanynamespace __asan { 34a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 35a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryanystatic void MaybeInstallSigaction(int signum, 36a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany void (*handler)(int, siginfo_t *, void *)) { 37a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany if (!AsanInterceptsSignal(signum)) 38a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany return; 39a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany struct sigaction sigact; 4009672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov REAL(memset)(&sigact, 0, sizeof(sigact)); 41a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany sigact.sa_sigaction = handler; 42a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany sigact.sa_flags = SA_SIGINFO; 4309672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov CHECK(0 == REAL(sigaction)(signum, &sigact, 0)); 44a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany} 45a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 46a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryanystatic void ASAN_OnSIGSEGV(int, siginfo_t *siginfo, void *context) { 47a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany uintptr_t addr = (uintptr_t)siginfo->si_addr; 48a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany // Write the first message using the bullet-proof write. 490ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryany if (13 != AsanWrite(2, "ASAN:SIGSEGV\n", 13)) AsanDie(); 50a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany uintptr_t pc, sp, bp; 51a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany GetPcSpBp(context, &pc, &sp, &bp); 52a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany Report("ERROR: AddressSanitizer crashed on unknown address %p" 53a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany " (pc %p sp %p bp %p T%d)\n", 54a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany addr, pc, sp, bp, 55a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany asanThreadRegistry().GetCurrentTidOrMinusOne()); 56a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany Printf("AddressSanitizer can not provide additional info. ABORTING\n"); 579cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, pc, bp); 58a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany stack.PrintStack(); 59a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany ShowStatsAndAbort(); 60a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany} 61a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 62a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryanyvoid InstallSignalHandlers() { 63a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany MaybeInstallSigaction(SIGSEGV, ASAN_OnSIGSEGV); 64a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany MaybeInstallSigaction(SIGBUS, ASAN_OnSIGSEGV); 65a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany} 66a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 67a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryanyvoid AsanDisableCoreDumper() { 68a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany struct rlimit nocore; 69a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany nocore.rlim_cur = 0; 70a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany nocore.rlim_max = 0; 71a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany setrlimit(RLIMIT_CORE, &nocore); 72a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany} 73a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 7499d17ebc36fe74326493bdd3dab4082ffc1dc96eAlexander Potapenkovoid AsanDumpProcessMap() { 7599d17ebc36fe74326493bdd3dab4082ffc1dc96eAlexander Potapenko AsanProcMaps proc_maps; 7699d17ebc36fe74326493bdd3dab4082ffc1dc96eAlexander Potapenko uintptr_t start, end; 7799d17ebc36fe74326493bdd3dab4082ffc1dc96eAlexander Potapenko const intptr_t kBufSize = 4095; 7899d17ebc36fe74326493bdd3dab4082ffc1dc96eAlexander Potapenko char filename[kBufSize]; 7999d17ebc36fe74326493bdd3dab4082ffc1dc96eAlexander Potapenko Report("Process memory map follows:\n"); 8099d17ebc36fe74326493bdd3dab4082ffc1dc96eAlexander Potapenko while (proc_maps.Next(&start, &end, /* file_offset */NULL, 8199d17ebc36fe74326493bdd3dab4082ffc1dc96eAlexander Potapenko filename, kBufSize)) { 8299d17ebc36fe74326493bdd3dab4082ffc1dc96eAlexander Potapenko Printf("\t%p-%p\t%s\n", (void*)start, (void*)end, filename); 8399d17ebc36fe74326493bdd3dab4082ffc1dc96eAlexander Potapenko } 8499d17ebc36fe74326493bdd3dab4082ffc1dc96eAlexander Potapenko Report("End of process memory map.\n"); 8599d17ebc36fe74326493bdd3dab4082ffc1dc96eAlexander Potapenko} 8699d17ebc36fe74326493bdd3dab4082ffc1dc96eAlexander Potapenko 870ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryanyint GetPid() { 880ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryany return getpid(); 890ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryany} 900ecf5eb729dd81a43f8585cb438d3cb2a35899edKostya Serebryany 91cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryanyuintptr_t GetThreadSelf() { 92cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany return (uintptr_t)pthread_self(); 93cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany} 94cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany 95e1fe0fd868886b53cb8d5d957afebbdd47688df7Kostya Serebryanyvoid SleepForSeconds(int seconds) { 96e1fe0fd868886b53cb8d5d957afebbdd47688df7Kostya Serebryany sleep(seconds); 97e1fe0fd868886b53cb8d5d957afebbdd47688df7Kostya Serebryany} 98e1fe0fd868886b53cb8d5d957afebbdd47688df7Kostya Serebryany 99e1fe0fd868886b53cb8d5d957afebbdd47688df7Kostya Serebryanyvoid Exit(int exitcode) { 100e1fe0fd868886b53cb8d5d957afebbdd47688df7Kostya Serebryany return _exit(exitcode); 101e1fe0fd868886b53cb8d5d957afebbdd47688df7Kostya Serebryany} 102e1fe0fd868886b53cb8d5d957afebbdd47688df7Kostya Serebryany 103b823e3c5f7891dbbde1eb288237f5f3d5ed64d85Alexey Samsonovint Atexit(void (*function)(void)) { 104b823e3c5f7891dbbde1eb288237f5f3d5ed64d85Alexey Samsonov return atexit(function); 105b823e3c5f7891dbbde1eb288237f5f3d5ed64d85Alexey Samsonov} 106b823e3c5f7891dbbde1eb288237f5f3d5ed64d85Alexey Samsonov 107dde7c33df06a9a0a8056f2357d764a10512206eeKostya Serebryanyint AtomicInc(int *a) { 108dde7c33df06a9a0a8056f2357d764a10512206eeKostya Serebryany#ifdef ANDROID 109dde7c33df06a9a0a8056f2357d764a10512206eeKostya Serebryany return __atomic_inc(a) + 1; 110dde7c33df06a9a0a8056f2357d764a10512206eeKostya Serebryany#else 111dde7c33df06a9a0a8056f2357d764a10512206eeKostya Serebryany return __sync_add_and_fetch(a, 1); 112dde7c33df06a9a0a8056f2357d764a10512206eeKostya Serebryany#endif 113dde7c33df06a9a0a8056f2357d764a10512206eeKostya Serebryany} 114dde7c33df06a9a0a8056f2357d764a10512206eeKostya Serebryany 115cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany// ---------------------- TSD ---------------- {{{1 116cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany 117cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryanystatic pthread_key_t tsd_key; 118cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryanystatic bool tsd_key_inited = false; 119f58f998066db0231e521169d2f50af439ceecb49Kostya Serebryanyvoid AsanTSDInit(void (*destructor)(void *tsd)) { 120cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany CHECK(!tsd_key_inited); 121cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany tsd_key_inited = true; 122f58f998066db0231e521169d2f50af439ceecb49Kostya Serebryany CHECK(0 == pthread_key_create(&tsd_key, destructor)); 123cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany} 124cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany 125cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryanyvoid *AsanTSDGet() { 126cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany CHECK(tsd_key_inited); 127cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany return pthread_getspecific(tsd_key); 128cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany} 129cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany 130cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryanyvoid AsanTSDSet(void *tsd) { 131cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany CHECK(tsd_key_inited); 132cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany pthread_setspecific(tsd_key, tsd); 133cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany} 134cc4e6862c6a8f8f3ead96bd32b815184a36fadedKostya Serebryany 135a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany} // namespace __asan 136a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany 137a7e760a53bc43b8e09bfdf5cd6f215267ba99729Kostya Serebryany#endif // __linux__ || __APPLE_ 138