asan_malloc_linux.cc revision 1e172b4bdec57329bf904f063a29f99cddf2d85f
11e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===-- asan_malloc_linux.cc ------------------------------------*- C++ -*-===// 21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The LLVM Compiler Infrastructure 41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source 61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details. 71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Linux-specific malloc interception. 131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// We simply define functions like malloc, free, realloc, etc. 141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// They will replace the corresponding libc functions automagically. 151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_allocator.h" 181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_interceptors.h" 191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h" 201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stack.h" 211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <malloc.h> 231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default"))) 251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#ifdef ANDROID 271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystruct MallocDebug { 281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany void* (*malloc)(size_t bytes); 291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany void (*free)(void* mem); 301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany void* (*calloc)(size_t n_elements, size_t elem_size); 311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany void* (*realloc)(void* oldMem, size_t bytes); 321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany void* (*memalign)(size_t alignment, size_t bytes); 331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}; 341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyconst MallocDebug asan_malloc_dispatch __attribute__((aligned(32))) = { 361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany malloc, free, calloc, realloc, memalign 371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany}; 381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" const MallocDebug* __libc_malloc_dispatch; 401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan { 421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid ReplaceSystemMalloc() { 431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany __libc_malloc_dispatch = &asan_malloc_dispatch; 441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // namespace __asan 461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#else // ANDROID 481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan { 501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid ReplaceSystemMalloc() { 511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // namespace __asan 531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#endif // ANDROID 541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// ---------------------- Replacement functions ---------------- {{{1 561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyusing namespace __asan; // NOLINT 571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" { 591e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyINTERCEPTOR_ATTRIBUTE 601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid free(void *ptr) { 611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE_FOR_FREE(ptr); 621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_free(ptr, &stack); 631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 651e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyINTERCEPTOR_ATTRIBUTE 661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid cfree(void *ptr) { 671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE_FOR_FREE(ptr); 681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_free(ptr, &stack); 691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 711e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyINTERCEPTOR_ATTRIBUTE 721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *malloc(size_t size) { 731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE_FOR_MALLOC; 741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return asan_malloc(size, &stack); 751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 771e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyINTERCEPTOR_ATTRIBUTE 781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *calloc(size_t nmemb, size_t size) { 791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (!asan_inited) { 801e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // Hack: dlsym calls calloc before real_calloc is retrieved from dlsym. 811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany const size_t kCallocPoolSize = 1024; 821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany static uintptr_t calloc_memory_for_dlsym[kCallocPoolSize]; 831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany static size_t allocated; 841e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany size_t size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize; 851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany void *mem = (void*)&calloc_memory_for_dlsym[allocated]; 861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany allocated += size_in_words; 871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany CHECK(allocated < kCallocPoolSize); 881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return mem; 891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE_FOR_MALLOC; 911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return asan_calloc(nmemb, size, &stack); 921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 941e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyINTERCEPTOR_ATTRIBUTE 951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *realloc(void *ptr, size_t size) { 961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE_FOR_MALLOC; 971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return asan_realloc(ptr, size, &stack); 981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1001e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyINTERCEPTOR_ATTRIBUTE 1011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *memalign(size_t boundary, size_t size) { 1021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE_FOR_MALLOC; 1031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return asan_memalign(boundary, size, &stack); 1041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid* __libc_memalign(size_t align, size_t s) 1071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany __attribute__((alias("memalign"))); 1081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1091e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyINTERCEPTOR_ATTRIBUTE 1101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanystruct mallinfo mallinfo() { 1111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany struct mallinfo res; 1121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany real_memset(&res, 0, sizeof(res)); 1131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return res; 1141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1161e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyINTERCEPTOR_ATTRIBUTE 1171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyint mallopt(int cmd, int value) { 1181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return -1; 1191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1211e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyINTERCEPTOR_ATTRIBUTE 1221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyint posix_memalign(void **memptr, size_t alignment, size_t size) { 1231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE_FOR_MALLOC; 1241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // Printf("posix_memalign: %lx %ld\n", alignment, size); 1251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return asan_posix_memalign(memptr, alignment, size, &stack); 1261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1281e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyINTERCEPTOR_ATTRIBUTE 1291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *valloc(size_t size) { 1301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE_FOR_MALLOC; 1311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return asan_valloc(size, &stack); 1321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1341e172b4bdec57329bf904f063a29f99cddf2d85fKostya SerebryanyINTERCEPTOR_ATTRIBUTE 1351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *pvalloc(size_t size) { 1361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE_FOR_MALLOC; 1371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return asan_pvalloc(size, &stack); 1381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // extern "C" 140