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