1e5f5895bda30f374b0b51412fd4d837fa59aed66Alexey Samsonov//===-- asan_interceptors.cc ----------------------------------------------===// 24d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov// 34d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov// The LLVM Compiler Infrastructure 44d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov// 54d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov// This file is distributed under the University of Illinois Open Source 64d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov// License. See LICENSE.TXT for details. 74d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov// 84d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov//===----------------------------------------------------------------------===// 94d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov// 104d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov// This file is a part of AddressSanitizer, an address sanity checker. 114d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov// 124d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov// Interceptors for operators new and delete. 134d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov//===----------------------------------------------------------------------===// 144d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov 154d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov#include "asan_allocator.h" 164d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov#include "asan_internal.h" 174d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov#include "asan_stack.h" 184d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov 192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_common/sanitizer_interception.h" 202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 21cfd605e96209d18c937501be870bd0308131e453Kostya Serebryany#include <stddef.h> 224d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov 232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// C++ operators can't have visibility attributes on Windows. 242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_WINDOWS 252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines# define CXX_OPERATOR_ATTRIBUTE 262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else 272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines# define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE 282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 294d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov 304d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonovusing namespace __asan; // NOLINT 314d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov 322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This code has issues on OSX. 332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// See https://code.google.com/p/address-sanitizer/issues/detail?id=131. 34dbe60352ef7240327f15f813140c9726854f6b85Evgeniy Stepanov 353aa15c1ad60ae6c63973a0982662f26449f661bcAlexey Samsonov// Fake std::nothrow_t to avoid including <new>. 363aa15c1ad60ae6c63973a0982662f26449f661bcAlexey Samsonovnamespace std { 373aa15c1ad60ae6c63973a0982662f26449f661bcAlexey Samsonovstruct nothrow_t {}; 383aa15c1ad60ae6c63973a0982662f26449f661bcAlexey Samsonov} // namespace std 393aa15c1ad60ae6c63973a0982662f26449f661bcAlexey Samsonov 40fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany#define OPERATOR_NEW_BODY(type) \ 41a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_MALLOC;\ 42fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany return asan_memalign(0, size, &stack, type); 434d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov 44d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko// On OS X it's not enough to just provide our own 'operator new' and 45d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko// 'operator delete' implementations, because they're going to be in the 46d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko// runtime dylib, and the main executable will depend on both the runtime 47d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko// dylib and libstdc++, each of those'll have its implementation of new and 48d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko// delete. 49d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko// To make sure that C++ allocation/deallocation operators are overridden on 50d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko// OS X we need to intercept them using their mangled names. 5124e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#if !SANITIZER_MAC 522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// FreeBSD prior v9.2 have wrong definition of 'size_t'. 532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// http://svnweb.freebsd.org/base?view=revision&revision=232261 542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32 552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <sys/param.h> 562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if __FreeBSD_version <= 902001 // v9.2 572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define size_t unsigned 582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif // __FreeBSD_version 592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif // SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32 602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE 62fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryanyvoid *operator new(size_t size) { OPERATOR_NEW_BODY(FROM_NEW); } 632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE 64fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryanyvoid *operator new[](size_t size) { OPERATOR_NEW_BODY(FROM_NEW_BR); } 652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE 66fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryanyvoid *operator new(size_t size, std::nothrow_t const&) 67fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany{ OPERATOR_NEW_BODY(FROM_NEW); } 682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE 69fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryanyvoid *operator new[](size_t size, std::nothrow_t const&) 70fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany{ OPERATOR_NEW_BODY(FROM_NEW_BR); } 714d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov 72649a270f5341efe9c57f473dbb78706b0b2ed523Alexey Samsonov#else // SANITIZER_MAC 73d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void *, _Znwm, size_t size) { 74d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko OPERATOR_NEW_BODY(FROM_NEW); 75d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko} 76d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void *, _Znam, size_t size) { 77d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko OPERATOR_NEW_BODY(FROM_NEW_BR); 78d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko} 79d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&) { 80d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko OPERATOR_NEW_BODY(FROM_NEW); 81d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko} 82d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) { 83d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko OPERATOR_NEW_BODY(FROM_NEW_BR); 84d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko} 85d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko#endif 86d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko 87fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany#define OPERATOR_DELETE_BODY(type) \ 88a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_FREE;\ 89fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany asan_free(ptr, &stack, type); 904d5f98df886051afeece1698d4bc8f154391c22dAlexey Samsonov 9124e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#if !SANITIZER_MAC 922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE 932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid operator delete(void *ptr) throw() { 942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines OPERATOR_DELETE_BODY(FROM_NEW); 952d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 962d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE 972d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid operator delete[](void *ptr) throw() { 982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines OPERATOR_DELETE_BODY(FROM_NEW_BR); 992d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1002d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE 1012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid operator delete(void *ptr, std::nothrow_t const&) { 1022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines OPERATOR_DELETE_BODY(FROM_NEW); 1032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 1042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesCXX_OPERATOR_ATTRIBUTE 1052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid operator delete[](void *ptr, std::nothrow_t const&) { 1062d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines OPERATOR_DELETE_BODY(FROM_NEW_BR); 1072d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 108dbe60352ef7240327f15f813140c9726854f6b85Evgeniy Stepanov 109649a270f5341efe9c57f473dbb78706b0b2ed523Alexey Samsonov#else // SANITIZER_MAC 110d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void, _ZdlPv, void *ptr) { 111d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko OPERATOR_DELETE_BODY(FROM_NEW); 112d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko} 113d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void, _ZdaPv, void *ptr) { 114d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko OPERATOR_DELETE_BODY(FROM_NEW_BR); 115d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko} 116d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { 117d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko OPERATOR_DELETE_BODY(FROM_NEW); 118d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko} 119d4228010624f7c6fa69934add3f9da46cc6b6918Alexander PotapenkoINTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { 120d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko OPERATOR_DELETE_BODY(FROM_NEW_BR); 121d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko} 122d4228010624f7c6fa69934add3f9da46cc6b6918Alexander Potapenko#endif 123