1 //===-- msan_new_delete.cpp -----------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file is a part of MemorySanitizer. 10 // 11 // Interceptors for operators new and delete. 12 //===----------------------------------------------------------------------===// 13 14 #include "msan.h" 15 #include "interception/interception.h" 16 #include "sanitizer_common/sanitizer_allocator.h" 17 #include "sanitizer_common/sanitizer_allocator_report.h" 18 19 #if MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 20 21 #include <stddef.h> 22 23 using namespace __msan; 24 25 // Fake std::nothrow_t and std::align_val_t to avoid including <new>. 26 namespace std { 27 struct nothrow_t {}; 28 enum class align_val_t: size_t {}; 29 } // namespace std 30 31 32 // TODO(alekseys): throw std::bad_alloc instead of dying on OOM. 33 #define OPERATOR_NEW_BODY(nothrow) \ 34 GET_MALLOC_STACK_TRACE; \ 35 void *res = msan_malloc(size, &stack);\ 36 if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\ 37 return res 38 #define OPERATOR_NEW_BODY_ALIGN(nothrow) \ 39 GET_MALLOC_STACK_TRACE;\ 40 void *res = msan_memalign((uptr)align, size, &stack);\ 41 if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\ 42 return res; 43 44 INTERCEPTOR_ATTRIBUTE 45 void *operator new(size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); } 46 INTERCEPTOR_ATTRIBUTE 47 void *operator new[](size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); } 48 INTERCEPTOR_ATTRIBUTE 49 void *operator new(size_t size, std::nothrow_t const&) { 50 OPERATOR_NEW_BODY(true /*nothrow*/); 51 } 52 INTERCEPTOR_ATTRIBUTE 53 void *operator new[](size_t size, std::nothrow_t const&) { 54 OPERATOR_NEW_BODY(true /*nothrow*/); 55 } 56 INTERCEPTOR_ATTRIBUTE 57 void *operator new(size_t size, std::align_val_t align) 58 { OPERATOR_NEW_BODY_ALIGN(false /*nothrow*/); } 59 INTERCEPTOR_ATTRIBUTE 60 void *operator new[](size_t size, std::align_val_t align) 61 { OPERATOR_NEW_BODY_ALIGN(false /*nothrow*/); } 62 INTERCEPTOR_ATTRIBUTE 63 void *operator new(size_t size, std::align_val_t align, std::nothrow_t const&) 64 { OPERATOR_NEW_BODY_ALIGN(true /*nothrow*/); } 65 INTERCEPTOR_ATTRIBUTE 66 void *operator new[](size_t size, std::align_val_t align, std::nothrow_t const&) 67 { OPERATOR_NEW_BODY_ALIGN(true /*nothrow*/); } 68 69 #define OPERATOR_DELETE_BODY \ 70 GET_MALLOC_STACK_TRACE; \ 71 if (ptr) MsanDeallocate(&stack, ptr) 72 73 INTERCEPTOR_ATTRIBUTE 74 void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; } 75 INTERCEPTOR_ATTRIBUTE 76 void operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; } 77 INTERCEPTOR_ATTRIBUTE 78 void operator delete(void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY; } 79 INTERCEPTOR_ATTRIBUTE 80 void operator delete[](void *ptr, std::nothrow_t const&) { 81 OPERATOR_DELETE_BODY; 82 } 83 INTERCEPTOR_ATTRIBUTE 84 void operator delete(void *ptr, size_t size) NOEXCEPT { OPERATOR_DELETE_BODY; } 85 INTERCEPTOR_ATTRIBUTE 86 void operator delete[](void *ptr, size_t size) NOEXCEPT 87 { OPERATOR_DELETE_BODY; } 88 INTERCEPTOR_ATTRIBUTE 89 void operator delete(void *ptr, std::align_val_t align) NOEXCEPT 90 { OPERATOR_DELETE_BODY; } 91 INTERCEPTOR_ATTRIBUTE 92 void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT 93 { OPERATOR_DELETE_BODY; } 94 INTERCEPTOR_ATTRIBUTE 95 void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&) 96 { OPERATOR_DELETE_BODY; } 97 INTERCEPTOR_ATTRIBUTE 98 void operator delete[](void *ptr, std::align_val_t align, std::nothrow_t const&) 99 { OPERATOR_DELETE_BODY; } 100 INTERCEPTOR_ATTRIBUTE 101 void operator delete(void *ptr, size_t size, std::align_val_t align) NOEXCEPT 102 { OPERATOR_DELETE_BODY; } 103 INTERCEPTOR_ATTRIBUTE 104 void operator delete[](void *ptr, size_t size, std::align_val_t align) NOEXCEPT 105 { OPERATOR_DELETE_BODY; } 106 107 108 #endif // MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 109