asan_malloc_linux.cc revision 24e13723f8477d8c42ab8b2a7f4f69fc089842f1
11510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org//===-- asan_malloc_linux.cc ----------------------------------------------===// 21510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// 31510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// The LLVM Compiler Infrastructure 41510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// 51510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// This file is distributed under the University of Illinois Open Source 61510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// License. See LICENSE.TXT for details. 71510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// 81510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org//===----------------------------------------------------------------------===// 91510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// 101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// This file is a part of AddressSanitizer, an address sanity checker. 111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// 121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// Linux-specific malloc interception. 131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// We simply define functions like malloc, free, realloc, etc. 141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// They will replace the corresponding libc functions automagically. 151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org//===----------------------------------------------------------------------===// 161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#include "sanitizer_common/sanitizer_platform.h" 181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#if SANITIZER_LINUX 191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#include "asan_allocator.h" 211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#include "asan_interceptors.h" 221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#include "asan_internal.h" 231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#include "asan_stack.h" 241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#include "asan_thread_registry.h" 251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org#if SANITIZER_ANDROID 271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDECLARE_REAL_AND_INTERCEPTOR(void*, malloc, uptr size) 281510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr) 291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDECLARE_REAL_AND_INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) 301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDECLARE_REAL_AND_INTERCEPTOR(void*, realloc, void *ptr, uptr size) 311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgDECLARE_REAL_AND_INTERCEPTOR(void*, memalign, uptr boundary, uptr size) 321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgstruct MallocDebug { 341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org void* (*malloc)(uptr bytes); 351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org void (*free)(void* mem); 361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org void* (*calloc)(uptr n_elements, uptr elem_size); 371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org void* (*realloc)(void* oldMem, uptr bytes); 381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org void* (*memalign)(uptr alignment, uptr bytes); 391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}; 401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgconst MallocDebug asan_malloc_dispatch ALIGNED(32) = { 421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org WRAP(malloc), WRAP(free), WRAP(calloc), WRAP(realloc), WRAP(memalign) 431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}; 441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgextern "C" const MallocDebug* __libc_malloc_dispatch; 46 47namespace __asan { 48void ReplaceSystemMalloc() { 49 __libc_malloc_dispatch = &asan_malloc_dispatch; 50} 51} // namespace __asan 52 53#else // ANDROID 54 55namespace __asan { 56void ReplaceSystemMalloc() { 57} 58} // namespace __asan 59#endif // ANDROID 60 61// ---------------------- Replacement functions ---------------- {{{1 62using namespace __asan; // NOLINT 63 64INTERCEPTOR(void, free, void *ptr) { 65 GET_STACK_TRACE_FREE; 66 asan_free(ptr, &stack, FROM_MALLOC); 67} 68 69INTERCEPTOR(void, cfree, void *ptr) { 70 GET_STACK_TRACE_FREE; 71 asan_free(ptr, &stack, FROM_MALLOC); 72} 73 74INTERCEPTOR(void*, malloc, uptr size) { 75 GET_STACK_TRACE_MALLOC; 76 return asan_malloc(size, &stack); 77} 78 79INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) { 80 if (!asan_inited) { 81 // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. 82 const uptr kCallocPoolSize = 1024; 83 static uptr calloc_memory_for_dlsym[kCallocPoolSize]; 84 static uptr allocated; 85 uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize; 86 void *mem = (void*)&calloc_memory_for_dlsym[allocated]; 87 allocated += size_in_words; 88 CHECK(allocated < kCallocPoolSize); 89 return mem; 90 } 91 GET_STACK_TRACE_MALLOC; 92 return asan_calloc(nmemb, size, &stack); 93} 94 95INTERCEPTOR(void*, realloc, void *ptr, uptr size) { 96 GET_STACK_TRACE_MALLOC; 97 return asan_realloc(ptr, size, &stack); 98} 99 100INTERCEPTOR(void*, memalign, uptr boundary, uptr size) { 101 GET_STACK_TRACE_MALLOC; 102 return asan_memalign(boundary, size, &stack, FROM_MALLOC); 103} 104 105INTERCEPTOR(void*, __libc_memalign, uptr align, uptr s) 106 ALIAS("memalign"); 107 108INTERCEPTOR(uptr, malloc_usable_size, void *ptr) { 109 GET_STACK_TRACE_MALLOC; 110 return asan_malloc_usable_size(ptr, &stack); 111} 112 113// We avoid including malloc.h for portability reasons. 114// man mallinfo says the fields are "long", but the implementation uses int. 115// It doesn't matter much -- we just need to make sure that the libc's mallinfo 116// is not called. 117struct fake_mallinfo { 118 int x[10]; 119}; 120 121INTERCEPTOR(struct fake_mallinfo, mallinfo, void) { 122 struct fake_mallinfo res; 123 REAL(memset)(&res, 0, sizeof(res)); 124 return res; 125} 126 127INTERCEPTOR(int, mallopt, int cmd, int value) { 128 return -1; 129} 130 131INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) { 132 GET_STACK_TRACE_MALLOC; 133 // Printf("posix_memalign: %zx %zu\n", alignment, size); 134 return asan_posix_memalign(memptr, alignment, size, &stack); 135} 136 137INTERCEPTOR(void*, valloc, uptr size) { 138 GET_STACK_TRACE_MALLOC; 139 return asan_valloc(size, &stack); 140} 141 142INTERCEPTOR(void*, pvalloc, uptr size) { 143 GET_STACK_TRACE_MALLOC; 144 return asan_pvalloc(size, &stack); 145} 146 147INTERCEPTOR(void, malloc_stats, void) { 148 __asan_print_accumulated_stats(); 149} 150 151#endif // __linux__ 152