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)