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