asan_linux.cc revision 10110f6539c5889109e7e2fa32973f1d5de8798c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- asan_linux.cc -----------------------------------------------------===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//===----------------------------------------------------------------------===// 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is a part of AddressSanitizer, an address sanity checker. 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Linux-specific details. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __linux__ 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "asan_interceptors.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "asan_internal.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "asan_lock.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "asan_thread.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "asan_thread_registry.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sanitizer_common/sanitizer_libc.h" 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "sanitizer_common/sanitizer_procmaps.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/time.h> 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/resource.h> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/mman.h> 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <sys/syscall.h> 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <sys/types.h> 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <fcntl.h> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <pthread.h> 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <unwind.h> 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if !ASAN_ANDROID 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FIXME: where to get ucontext on Android? 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/ucontext.h> 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" void* _DYNAMIC; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace __asan { 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MaybeReexec() { 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // No need to re-exec on Linux. 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void *AsanDoesNotSupportStaticLinkage() { 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This will fail to link with -static. 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return &_DYNAMIC; // defined in link.h 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if ASAN_ANDROID 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *pc = *sp = *bp = 0; 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#elif defined(__arm__) 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ucontext_t *ucontext = (ucontext_t*)context; 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *pc = ucontext->uc_mcontext.arm_pc; 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *bp = ucontext->uc_mcontext.arm_fp; 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *sp = ucontext->uc_mcontext.arm_sp; 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# elif defined(__x86_64__) 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ucontext_t *ucontext = (ucontext_t*)context; 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *pc = ucontext->uc_mcontext.gregs[REG_RIP]; 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *bp = ucontext->uc_mcontext.gregs[REG_RBP]; 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *sp = ucontext->uc_mcontext.gregs[REG_RSP]; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# elif defined(__i386__) 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ucontext_t *ucontext = (ucontext_t*)context; 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *pc = ucontext->uc_mcontext.gregs[REG_EIP]; 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *bp = ucontext->uc_mcontext.gregs[REG_EBP]; 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *sp = ucontext->uc_mcontext.gregs[REG_ESP]; 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch# elif defined(__powerpc__) || defined(__powerpc64__) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ucontext_t *ucontext = (ucontext_t*)context; 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *pc = ucontext->uc_mcontext.regs->nip; 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *sp = ucontext->uc_mcontext.regs->gpr[PT_R1]; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The powerpc{,64}-linux ABIs do not specify r31 as the frame 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pointer, but GCC always uses r31 when we need a frame pointer. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp = ucontext->uc_mcontext.regs->gpr[PT_R31]; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# elif defined(__sparc__) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ucontext_t *ucontext = (ucontext_t*)context; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uptr *stk_ptr; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# if defined (__arch64__) 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *pc = ucontext->uc_mcontext.mc_gregs[MC_PC]; 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *sp = ucontext->uc_mcontext.mc_gregs[MC_O6]; 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stk_ptr = (uptr *) (*sp + 2047); 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *bp = stk_ptr[15]; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# else 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pc = ucontext->uc_mcontext.gregs[REG_PC]; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *sp = ucontext->uc_mcontext.gregs[REG_O6]; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stk_ptr = (uptr *) *sp; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bp = stk_ptr[15]; 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# endif 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# error "Unsupported arch" 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool AsanInterceptsSignal(int signum) { 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return signum == SIGSEGV && flags()->handle_segv; 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AsanPlatformThreadInit() { 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Nothing here for now. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AsanLock::AsanLock(LinkerInitialized) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We assume that pthread_mutex_t initialized to all zeroes is a valid 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unlocked mutex. We can not use PTHREAD_MUTEX_INITIALIZER as it triggers 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a gcc warning: 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extended initializer lists only available with -std=c++0x or -std=gnu++0x 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AsanLock::Lock() { 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(sizeof(pthread_mutex_t) <= sizeof(opaque_storage_)); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_mutex_lock((pthread_mutex_t*)&opaque_storage_); 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CHECK(!owner_); 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) owner_ = (uptr)pthread_self(); 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AsanLock::Unlock() { 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CHECK(owner_ == (uptr)pthread_self()); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owner_ = 0; 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pthread_mutex_unlock((pthread_mutex_t*)&opaque_storage_); 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifdef __arm__ 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define UNWIND_STOP _URC_END_OF_STACK 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define UNWIND_CONTINUE _URC_NO_REASON 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#else 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UNWIND_STOP _URC_NORMAL_STOP 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UNWIND_CONTINUE _URC_NO_REASON 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uptr Unwind_GetIP(struct _Unwind_Context *ctx) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __arm__ 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uptr val; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _Unwind_VRS_Result res = _Unwind_VRS_Get(ctx, _UVRSC_CORE, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15 /* r15 = PC */, _UVRSD_UINT32, &val); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(res == _UVRSR_OK && "_Unwind_VRS_Get failed"); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the Thumb bit. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return val & ~(uptr)1; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return _Unwind_GetIP(ctx); 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void *param) { 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StackTrace *b = (StackTrace*)param; 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(b->size < b->max_size); 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uptr pc = Unwind_GetIP(ctx); 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) b->trace[b->size++] = pc; 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (b->size == b->max_size) return UNWIND_STOP; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UNWIND_CONTINUE; 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp) { 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stack->size = 0; 15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stack->trace[0] = pc; 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((max_s) > 1) { 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stack->max_size = max_s; 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(__arm__) || defined(__powerpc__) || defined(__powerpc64__) 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) _Unwind_Backtrace(Unwind_Trace, stack); 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Pop off the two ASAN functions from the backtrace. 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stack->PopStackFrames(2); 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!asan_inited) return; 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (AsanThread *t = asanThreadRegistry().GetCurrent()) 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stack->FastUnwindStack(pc, bp, t->stack_top(), t->stack_bottom()); 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace __asan 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // __linux__ 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)