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_interface.h" 18 #include "sanitizer_common/sanitizer_tls_get_addr.h" 19 20 #if !SANITIZER_FUCHSIA 21 22 using namespace __hwasan; 23 24 static uptr allocated_for_dlsym; 25 static const uptr kDlsymAllocPoolSize = 1024; 26 static uptr alloc_memory_for_dlsym[kDlsymAllocPoolSize]; 27 28 static bool IsInDlsymAllocPool(const void *ptr) { 29 uptr off = (uptr)ptr - (uptr)alloc_memory_for_dlsym; 30 return off < sizeof(alloc_memory_for_dlsym); 31 } 32 33 static void *AllocateFromLocalPool(uptr size_in_bytes) { 34 uptr size_in_words = RoundUpTo(size_in_bytes, kWordSize) / kWordSize; 35 void *mem = (void *)&alloc_memory_for_dlsym[allocated_for_dlsym]; 36 allocated_for_dlsym += size_in_words; 37 CHECK_LT(allocated_for_dlsym, kDlsymAllocPoolSize); 38 return mem; 39 } 40 41 extern "C" { 42 43 SANITIZER_INTERFACE_ATTRIBUTE 44 int __sanitizer_posix_memalign(void **memptr, uptr alignment, uptr size) { 45 GET_MALLOC_STACK_TRACE; 46 CHECK_NE(memptr, 0); 47 int res = hwasan_posix_memalign(memptr, alignment, size, &stack); 48 return res; 49 } 50 51 SANITIZER_INTERFACE_ATTRIBUTE 52 void *__sanitizer_memalign(uptr alignment, uptr size) { 53 GET_MALLOC_STACK_TRACE; 54 return hwasan_memalign(alignment, size, &stack); 55 } 56 57 SANITIZER_INTERFACE_ATTRIBUTE 58 void *__sanitizer_aligned_alloc(uptr alignment, uptr size) { 59 GET_MALLOC_STACK_TRACE; 60 return hwasan_aligned_alloc(alignment, size, &stack); 61 } 62 63 SANITIZER_INTERFACE_ATTRIBUTE 64 void *__sanitizer___libc_memalign(uptr alignment, uptr size) { 65 GET_MALLOC_STACK_TRACE; 66 void *ptr = hwasan_memalign(alignment, size, &stack); 67 if (ptr) 68 DTLS_on_libc_memalign(ptr, size); 69 return ptr; 70 } 71 72 SANITIZER_INTERFACE_ATTRIBUTE 73 void *__sanitizer_valloc(uptr size) { 74 GET_MALLOC_STACK_TRACE; 75 return hwasan_valloc(size, &stack); 76 } 77 78 SANITIZER_INTERFACE_ATTRIBUTE 79 void *__sanitizer_pvalloc(uptr size) { 80 GET_MALLOC_STACK_TRACE; 81 return hwasan_pvalloc(size, &stack); 82 } 83 84 SANITIZER_INTERFACE_ATTRIBUTE 85 void __sanitizer_free(void *ptr) { 86 GET_MALLOC_STACK_TRACE; 87 if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) 88 return; 89 hwasan_free(ptr, &stack); 90 } 91 92 SANITIZER_INTERFACE_ATTRIBUTE 93 void __sanitizer_cfree(void *ptr) { 94 GET_MALLOC_STACK_TRACE; 95 if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) 96 return; 97 hwasan_free(ptr, &stack); 98 } 99 100 SANITIZER_INTERFACE_ATTRIBUTE 101 uptr __sanitizer_malloc_usable_size(const void *ptr) { 102 return __sanitizer_get_allocated_size(ptr); 103 } 104 105 SANITIZER_INTERFACE_ATTRIBUTE 106 struct __sanitizer_struct_mallinfo __sanitizer_mallinfo() { 107 __sanitizer_struct_mallinfo sret; 108 internal_memset(&sret, 0, sizeof(sret)); 109 return sret; 110 } 111 112 SANITIZER_INTERFACE_ATTRIBUTE 113 int __sanitizer_mallopt(int cmd, int value) { return 0; } 114 115 SANITIZER_INTERFACE_ATTRIBUTE 116 void __sanitizer_malloc_stats(void) { 117 // FIXME: implement, but don't call REAL(malloc_stats)! 118 } 119 120 SANITIZER_INTERFACE_ATTRIBUTE 121 void *__sanitizer_calloc(uptr nmemb, uptr size) { 122 GET_MALLOC_STACK_TRACE; 123 if (UNLIKELY(!hwasan_inited)) 124 // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. 125 return AllocateFromLocalPool(nmemb * size); 126 return hwasan_calloc(nmemb, size, &stack); 127 } 128 129 SANITIZER_INTERFACE_ATTRIBUTE 130 void *__sanitizer_realloc(void *ptr, uptr size) { 131 GET_MALLOC_STACK_TRACE; 132 if (UNLIKELY(IsInDlsymAllocPool(ptr))) { 133 uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym; 134 uptr copy_size = Min(size, kDlsymAllocPoolSize - offset); 135 void *new_ptr; 136 if (UNLIKELY(!hwasan_inited)) { 137 new_ptr = AllocateFromLocalPool(copy_size); 138 } else { 139 copy_size = size; 140 new_ptr = hwasan_malloc(copy_size, &stack); 141 } 142 internal_memcpy(new_ptr, ptr, copy_size); 143 return new_ptr; 144 } 145 return hwasan_realloc(ptr, size, &stack); 146 } 147 148 SANITIZER_INTERFACE_ATTRIBUTE 149 void *__sanitizer_reallocarray(void *ptr, uptr nmemb, uptr size) { 150 GET_MALLOC_STACK_TRACE; 151 return hwasan_reallocarray(ptr, nmemb, size, &stack); 152 } 153 154 SANITIZER_INTERFACE_ATTRIBUTE 155 void *__sanitizer_malloc(uptr size) { 156 GET_MALLOC_STACK_TRACE; 157 if (UNLIKELY(!hwasan_init_is_running)) 158 ENSURE_HWASAN_INITED(); 159 if (UNLIKELY(!hwasan_inited)) 160 // Hack: dlsym calls malloc before REAL(malloc) is retrieved from dlsym. 161 return AllocateFromLocalPool(size); 162 return hwasan_malloc(size, &stack); 163 } 164 165 } // extern "C" 166 167 #if HWASAN_WITH_INTERCEPTORS 168 # define INTERCEPTOR_ALIAS(RET, FN, ARGS...) \ 169 extern "C" SANITIZER_INTERFACE_ATTRIBUTE RET WRAP(FN)(ARGS) \ 170 ALIAS("__sanitizer_" #FN); \ 171 extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE RET FN( \ 172 ARGS) ALIAS("__sanitizer_" #FN) 173 174 INTERCEPTOR_ALIAS(int, posix_memalign, void **memptr, SIZE_T alignment, 175 SIZE_T size); 176 INTERCEPTOR_ALIAS(void *, aligned_alloc, SIZE_T alignment, SIZE_T size); 177 INTERCEPTOR_ALIAS(void *, __libc_memalign, SIZE_T alignment, SIZE_T size); 178 INTERCEPTOR_ALIAS(void *, valloc, SIZE_T size); 179 INTERCEPTOR_ALIAS(void, free, void *ptr); 180 INTERCEPTOR_ALIAS(uptr, malloc_usable_size, const void *ptr); 181 INTERCEPTOR_ALIAS(void *, calloc, SIZE_T nmemb, SIZE_T size); 182 INTERCEPTOR_ALIAS(void *, realloc, void *ptr, SIZE_T size); 183 INTERCEPTOR_ALIAS(void *, reallocarray, void *ptr, SIZE_T nmemb, SIZE_T size); 184 INTERCEPTOR_ALIAS(void *, malloc, SIZE_T size); 185 186 # if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 187 INTERCEPTOR_ALIAS(void *, memalign, SIZE_T alignment, SIZE_T size); 188 INTERCEPTOR_ALIAS(void *, pvalloc, SIZE_T size); 189 INTERCEPTOR_ALIAS(void, cfree, void *ptr); 190 INTERCEPTOR_ALIAS(__sanitizer_struct_mallinfo, mallinfo); 191 INTERCEPTOR_ALIAS(int, mallopt, int cmd, int value); 192 INTERCEPTOR_ALIAS(void, malloc_stats, void); 193 # endif 194 #endif // #if HWASAN_WITH_INTERCEPTORS 195 196 #endif // SANITIZER_FUCHSIA 197