1 //===-- hwasan_allocation_functions.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 HWAddressSanitizer. 10 // 11 // Definitions for __sanitizer allocation functions. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "hwasan.h" 16 #include "interception/interception.h" 17 #include "sanitizer_common/sanitizer_allocator_dlsym.h" 18 #include "sanitizer_common/sanitizer_allocator_interface.h" 19 #include "sanitizer_common/sanitizer_mallinfo.h" 20 21 using namespace __hwasan; 22 23 struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> { 24 static bool UseImpl() { return !hwasan_inited; } 25 static void OnAllocate(const void *ptr, uptr size) { 26 # if CAN_SANITIZE_LEAKS 27 // Suppress leaks from dlerror(). Previously dlsym hack on global array was 28 // used by leak sanitizer as a root region. 29 __lsan_register_root_region(ptr, size); 30 # endif 31 } 32 static void OnFree(const void *ptr, uptr size) { 33 # if CAN_SANITIZE_LEAKS 34 __lsan_unregister_root_region(ptr, size); 35 # endif 36 } 37 }; 38 39 extern "C" { 40 41 SANITIZER_INTERFACE_ATTRIBUTE 42 int __sanitizer_posix_memalign(void **memptr, uptr alignment, uptr size) { 43 GET_MALLOC_STACK_TRACE; 44 CHECK_NE(memptr, 0); 45 int res = hwasan_posix_memalign(memptr, alignment, size, &stack); 46 return res; 47 } 48 49 SANITIZER_INTERFACE_ATTRIBUTE 50 void *__sanitizer_memalign(uptr alignment, uptr size) { 51 GET_MALLOC_STACK_TRACE; 52 return hwasan_memalign(alignment, size, &stack); 53 } 54 55 SANITIZER_INTERFACE_ATTRIBUTE 56 void *__sanitizer_aligned_alloc(uptr alignment, uptr size) { 57 GET_MALLOC_STACK_TRACE; 58 return hwasan_aligned_alloc(alignment, size, &stack); 59 } 60 61 SANITIZER_INTERFACE_ATTRIBUTE 62 void *__sanitizer___libc_memalign(uptr alignment, uptr size) { 63 GET_MALLOC_STACK_TRACE; 64 return hwasan_memalign(alignment, size, &stack); 65 } 66 67 SANITIZER_INTERFACE_ATTRIBUTE 68 void *__sanitizer_valloc(uptr size) { 69 GET_MALLOC_STACK_TRACE; 70 return hwasan_valloc(size, &stack); 71 } 72 73 SANITIZER_INTERFACE_ATTRIBUTE 74 void *__sanitizer_pvalloc(uptr size) { 75 GET_MALLOC_STACK_TRACE; 76 return hwasan_pvalloc(size, &stack); 77 } 78 79 SANITIZER_INTERFACE_ATTRIBUTE 80 void __sanitizer_free(void *ptr) { 81 if (!ptr) 82 return; 83 if (DlsymAlloc::PointerIsMine(ptr)) 84 return DlsymAlloc::Free(ptr); 85 GET_MALLOC_STACK_TRACE; 86 hwasan_free(ptr, &stack); 87 } 88 89 SANITIZER_INTERFACE_ATTRIBUTE 90 void __sanitizer_cfree(void *ptr) { 91 if (!ptr) 92 return; 93 if (DlsymAlloc::PointerIsMine(ptr)) 94 return DlsymAlloc::Free(ptr); 95 GET_MALLOC_STACK_TRACE; 96 hwasan_free(ptr, &stack); 97 } 98 99 SANITIZER_INTERFACE_ATTRIBUTE 100 uptr __sanitizer_malloc_usable_size(const void *ptr) { 101 return __sanitizer_get_allocated_size(ptr); 102 } 103 104 SANITIZER_INTERFACE_ATTRIBUTE 105 struct __sanitizer_struct_mallinfo __sanitizer_mallinfo() { 106 __sanitizer_struct_mallinfo sret; 107 internal_memset(&sret, 0, sizeof(sret)); 108 return sret; 109 } 110 111 SANITIZER_INTERFACE_ATTRIBUTE 112 int __sanitizer_mallopt(int cmd, int value) { return 0; } 113 114 SANITIZER_INTERFACE_ATTRIBUTE 115 void __sanitizer_malloc_stats(void) { 116 // FIXME: implement, but don't call REAL(malloc_stats)! 117 } 118 119 SANITIZER_INTERFACE_ATTRIBUTE 120 void *__sanitizer_calloc(uptr nmemb, uptr size) { 121 if (DlsymAlloc::Use()) 122 return DlsymAlloc::Callocate(nmemb, size); 123 GET_MALLOC_STACK_TRACE; 124 return hwasan_calloc(nmemb, size, &stack); 125 } 126 127 SANITIZER_INTERFACE_ATTRIBUTE 128 void *__sanitizer_realloc(void *ptr, uptr size) { 129 if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr)) 130 return DlsymAlloc::Realloc(ptr, size); 131 GET_MALLOC_STACK_TRACE; 132 return hwasan_realloc(ptr, size, &stack); 133 } 134 135 SANITIZER_INTERFACE_ATTRIBUTE 136 void *__sanitizer_reallocarray(void *ptr, uptr nmemb, uptr size) { 137 GET_MALLOC_STACK_TRACE; 138 return hwasan_reallocarray(ptr, nmemb, size, &stack); 139 } 140 141 SANITIZER_INTERFACE_ATTRIBUTE 142 void *__sanitizer_malloc(uptr size) { 143 if (UNLIKELY(!hwasan_init_is_running)) 144 ENSURE_HWASAN_INITED(); 145 if (DlsymAlloc::Use()) 146 return DlsymAlloc::Allocate(size); 147 GET_MALLOC_STACK_TRACE; 148 return hwasan_malloc(size, &stack); 149 } 150 151 } // extern "C" 152 153 #if HWASAN_WITH_INTERCEPTORS || SANITIZER_FUCHSIA 154 #if SANITIZER_FUCHSIA 155 // Fuchsia does not use WRAP/wrappers used for the interceptor infrastructure. 156 # define INTERCEPTOR_ALIAS(RET, FN, ARGS...) \ 157 extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE RET FN( \ 158 ARGS) ALIAS(__sanitizer_##FN) 159 #else 160 # define INTERCEPTOR_ALIAS(RET, FN, ARGS...) \ 161 extern "C" SANITIZER_INTERFACE_ATTRIBUTE RET WRAP(FN)(ARGS) \ 162 ALIAS(__sanitizer_##FN); \ 163 extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE RET FN( \ 164 ARGS) ALIAS(__sanitizer_##FN) 165 #endif 166 167 INTERCEPTOR_ALIAS(int, posix_memalign, void **memptr, SIZE_T alignment, 168 SIZE_T size); 169 INTERCEPTOR_ALIAS(void *, aligned_alloc, SIZE_T alignment, SIZE_T size); 170 INTERCEPTOR_ALIAS(void *, __libc_memalign, SIZE_T alignment, SIZE_T size); 171 INTERCEPTOR_ALIAS(void *, valloc, SIZE_T size); 172 INTERCEPTOR_ALIAS(void, free, void *ptr); 173 INTERCEPTOR_ALIAS(uptr, malloc_usable_size, const void *ptr); 174 INTERCEPTOR_ALIAS(void *, calloc, SIZE_T nmemb, SIZE_T size); 175 INTERCEPTOR_ALIAS(void *, realloc, void *ptr, SIZE_T size); 176 INTERCEPTOR_ALIAS(void *, reallocarray, void *ptr, SIZE_T nmemb, SIZE_T size); 177 INTERCEPTOR_ALIAS(void *, malloc, SIZE_T size); 178 179 # if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 180 INTERCEPTOR_ALIAS(void *, memalign, SIZE_T alignment, SIZE_T size); 181 INTERCEPTOR_ALIAS(void *, pvalloc, SIZE_T size); 182 INTERCEPTOR_ALIAS(void, cfree, void *ptr); 183 INTERCEPTOR_ALIAS(__sanitizer_struct_mallinfo, mallinfo,); 184 INTERCEPTOR_ALIAS(int, mallopt, int cmd, int value); 185 INTERCEPTOR_ALIAS(void, malloc_stats, void); 186 # endif 187 #endif // #if HWASAN_WITH_INTERCEPTORS 188