1944b3c53SLeonard Chan //===-- hwasan_allocation_functions.cpp -----------------------------------===// 2944b3c53SLeonard Chan // 3944b3c53SLeonard Chan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4944b3c53SLeonard Chan // See https://llvm.org/LICENSE.txt for license information. 5944b3c53SLeonard Chan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6944b3c53SLeonard Chan // 7944b3c53SLeonard Chan //===----------------------------------------------------------------------===// 8944b3c53SLeonard Chan // 9944b3c53SLeonard Chan // This file is a part of HWAddressSanitizer. 10944b3c53SLeonard Chan // 11944b3c53SLeonard Chan // Definitions for __sanitizer allocation functions. 12944b3c53SLeonard Chan // 13944b3c53SLeonard Chan //===----------------------------------------------------------------------===// 14944b3c53SLeonard Chan 15944b3c53SLeonard Chan #include "hwasan.h" 16944b3c53SLeonard Chan #include "interception/interception.h" 17cb0e14ceSVitaly Buka #include "sanitizer_common/sanitizer_allocator_dlsym.h" 18944b3c53SLeonard Chan #include "sanitizer_common/sanitizer_allocator_interface.h" 196680d4e4SLeonard Chan #include "sanitizer_common/sanitizer_mallinfo.h" 20944b3c53SLeonard Chan 21944b3c53SLeonard Chan using namespace __hwasan; 22944b3c53SLeonard Chan 23cb0e14ceSVitaly Buka struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> { 24cb0e14ceSVitaly Buka static bool UseImpl() { return !hwasan_inited; } 25ca0fab0cSLeonard Chan static void OnAllocate(const void *ptr, uptr size) { 26ca0fab0cSLeonard Chan # if CAN_SANITIZE_LEAKS 27ca0fab0cSLeonard Chan // Suppress leaks from dlerror(). Previously dlsym hack on global array was 28ca0fab0cSLeonard Chan // used by leak sanitizer as a root region. 29ca0fab0cSLeonard Chan __lsan_register_root_region(ptr, size); 30ca0fab0cSLeonard Chan # endif 31ca0fab0cSLeonard Chan } 32ca0fab0cSLeonard Chan static void OnFree(const void *ptr, uptr size) { 33ca0fab0cSLeonard Chan # if CAN_SANITIZE_LEAKS 34ca0fab0cSLeonard Chan __lsan_unregister_root_region(ptr, size); 35ca0fab0cSLeonard Chan # endif 36ca0fab0cSLeonard Chan } 37cb0e14ceSVitaly Buka }; 38944b3c53SLeonard Chan 39b4c00b38SLeonard Chan extern "C" { 40b4c00b38SLeonard Chan 41b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 42944b3c53SLeonard Chan int __sanitizer_posix_memalign(void **memptr, uptr alignment, uptr size) { 43944b3c53SLeonard Chan GET_MALLOC_STACK_TRACE; 44944b3c53SLeonard Chan CHECK_NE(memptr, 0); 45944b3c53SLeonard Chan int res = hwasan_posix_memalign(memptr, alignment, size, &stack); 46944b3c53SLeonard Chan return res; 47944b3c53SLeonard Chan } 48944b3c53SLeonard Chan 49b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 50944b3c53SLeonard Chan void *__sanitizer_memalign(uptr alignment, uptr size) { 51944b3c53SLeonard Chan GET_MALLOC_STACK_TRACE; 52944b3c53SLeonard Chan return hwasan_memalign(alignment, size, &stack); 53944b3c53SLeonard Chan } 54944b3c53SLeonard Chan 55b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 56944b3c53SLeonard Chan void *__sanitizer_aligned_alloc(uptr alignment, uptr size) { 57944b3c53SLeonard Chan GET_MALLOC_STACK_TRACE; 58944b3c53SLeonard Chan return hwasan_aligned_alloc(alignment, size, &stack); 59944b3c53SLeonard Chan } 60944b3c53SLeonard Chan 61b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 62944b3c53SLeonard Chan void *__sanitizer___libc_memalign(uptr alignment, uptr size) { 63944b3c53SLeonard Chan GET_MALLOC_STACK_TRACE; 64*b07f1be9SVitaly Buka return hwasan_memalign(alignment, size, &stack); 65944b3c53SLeonard Chan } 66944b3c53SLeonard Chan 67b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 68944b3c53SLeonard Chan void *__sanitizer_valloc(uptr size) { 69944b3c53SLeonard Chan GET_MALLOC_STACK_TRACE; 70944b3c53SLeonard Chan return hwasan_valloc(size, &stack); 71944b3c53SLeonard Chan } 72944b3c53SLeonard Chan 73b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 74944b3c53SLeonard Chan void *__sanitizer_pvalloc(uptr size) { 75944b3c53SLeonard Chan GET_MALLOC_STACK_TRACE; 76944b3c53SLeonard Chan return hwasan_pvalloc(size, &stack); 77944b3c53SLeonard Chan } 78944b3c53SLeonard Chan 79b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 80944b3c53SLeonard Chan void __sanitizer_free(void *ptr) { 81cb0e14ceSVitaly Buka if (!ptr) 82944b3c53SLeonard Chan return; 83cb0e14ceSVitaly Buka if (DlsymAlloc::PointerIsMine(ptr)) 84cb0e14ceSVitaly Buka return DlsymAlloc::Free(ptr); 85651797f4SVitaly Buka GET_MALLOC_STACK_TRACE; 86944b3c53SLeonard Chan hwasan_free(ptr, &stack); 87944b3c53SLeonard Chan } 88944b3c53SLeonard Chan 89b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 90944b3c53SLeonard Chan void __sanitizer_cfree(void *ptr) { 91cb0e14ceSVitaly Buka if (!ptr) 92944b3c53SLeonard Chan return; 93cb0e14ceSVitaly Buka if (DlsymAlloc::PointerIsMine(ptr)) 94cb0e14ceSVitaly Buka return DlsymAlloc::Free(ptr); 95651797f4SVitaly Buka GET_MALLOC_STACK_TRACE; 96944b3c53SLeonard Chan hwasan_free(ptr, &stack); 97944b3c53SLeonard Chan } 98944b3c53SLeonard Chan 99b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 100944b3c53SLeonard Chan uptr __sanitizer_malloc_usable_size(const void *ptr) { 101944b3c53SLeonard Chan return __sanitizer_get_allocated_size(ptr); 102944b3c53SLeonard Chan } 103944b3c53SLeonard Chan 104b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 105944b3c53SLeonard Chan struct __sanitizer_struct_mallinfo __sanitizer_mallinfo() { 106944b3c53SLeonard Chan __sanitizer_struct_mallinfo sret; 107944b3c53SLeonard Chan internal_memset(&sret, 0, sizeof(sret)); 108944b3c53SLeonard Chan return sret; 109944b3c53SLeonard Chan } 110944b3c53SLeonard Chan 111b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 112944b3c53SLeonard Chan int __sanitizer_mallopt(int cmd, int value) { return 0; } 113944b3c53SLeonard Chan 114b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 115944b3c53SLeonard Chan void __sanitizer_malloc_stats(void) { 116944b3c53SLeonard Chan // FIXME: implement, but don't call REAL(malloc_stats)! 117944b3c53SLeonard Chan } 118944b3c53SLeonard Chan 119b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 120944b3c53SLeonard Chan void *__sanitizer_calloc(uptr nmemb, uptr size) { 121cb0e14ceSVitaly Buka if (DlsymAlloc::Use()) 122cb0e14ceSVitaly Buka return DlsymAlloc::Callocate(nmemb, size); 123651797f4SVitaly Buka GET_MALLOC_STACK_TRACE; 124944b3c53SLeonard Chan return hwasan_calloc(nmemb, size, &stack); 125944b3c53SLeonard Chan } 126944b3c53SLeonard Chan 127b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 128944b3c53SLeonard Chan void *__sanitizer_realloc(void *ptr, uptr size) { 129cb0e14ceSVitaly Buka if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr)) 130cb0e14ceSVitaly Buka return DlsymAlloc::Realloc(ptr, size); 131651797f4SVitaly Buka GET_MALLOC_STACK_TRACE; 132944b3c53SLeonard Chan return hwasan_realloc(ptr, size, &stack); 133944b3c53SLeonard Chan } 134944b3c53SLeonard Chan 135b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 136944b3c53SLeonard Chan void *__sanitizer_reallocarray(void *ptr, uptr nmemb, uptr size) { 137944b3c53SLeonard Chan GET_MALLOC_STACK_TRACE; 138944b3c53SLeonard Chan return hwasan_reallocarray(ptr, nmemb, size, &stack); 139944b3c53SLeonard Chan } 140944b3c53SLeonard Chan 141b4c00b38SLeonard Chan SANITIZER_INTERFACE_ATTRIBUTE 142944b3c53SLeonard Chan void *__sanitizer_malloc(uptr size) { 143944b3c53SLeonard Chan if (UNLIKELY(!hwasan_init_is_running)) 144944b3c53SLeonard Chan ENSURE_HWASAN_INITED(); 145cb0e14ceSVitaly Buka if (DlsymAlloc::Use()) 146cb0e14ceSVitaly Buka return DlsymAlloc::Allocate(size); 147651797f4SVitaly Buka GET_MALLOC_STACK_TRACE; 148944b3c53SLeonard Chan return hwasan_malloc(size, &stack); 149944b3c53SLeonard Chan } 150944b3c53SLeonard Chan 151b4c00b38SLeonard Chan } // extern "C" 152b4c00b38SLeonard Chan 1536680d4e4SLeonard Chan #if HWASAN_WITH_INTERCEPTORS || SANITIZER_FUCHSIA 1546680d4e4SLeonard Chan #if SANITIZER_FUCHSIA 1556680d4e4SLeonard Chan // Fuchsia does not use WRAP/wrappers used for the interceptor infrastructure. 1566680d4e4SLeonard Chan # define INTERCEPTOR_ALIAS(RET, FN, ARGS...) \ 1576680d4e4SLeonard Chan extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE RET FN( \ 158175fcd6fSMarco Elver ARGS) ALIAS(__sanitizer_##FN) 1596680d4e4SLeonard Chan #else 160944b3c53SLeonard Chan # define INTERCEPTOR_ALIAS(RET, FN, ARGS...) \ 1617b6c0ce9SLeonard Chan extern "C" SANITIZER_INTERFACE_ATTRIBUTE RET WRAP(FN)(ARGS) \ 162175fcd6fSMarco Elver ALIAS(__sanitizer_##FN); \ 163944b3c53SLeonard Chan extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE RET FN( \ 164175fcd6fSMarco Elver ARGS) ALIAS(__sanitizer_##FN) 1656680d4e4SLeonard Chan #endif 166944b3c53SLeonard Chan 167944b3c53SLeonard Chan INTERCEPTOR_ALIAS(int, posix_memalign, void **memptr, SIZE_T alignment, 168944b3c53SLeonard Chan SIZE_T size); 169944b3c53SLeonard Chan INTERCEPTOR_ALIAS(void *, aligned_alloc, SIZE_T alignment, SIZE_T size); 170944b3c53SLeonard Chan INTERCEPTOR_ALIAS(void *, __libc_memalign, SIZE_T alignment, SIZE_T size); 171944b3c53SLeonard Chan INTERCEPTOR_ALIAS(void *, valloc, SIZE_T size); 172944b3c53SLeonard Chan INTERCEPTOR_ALIAS(void, free, void *ptr); 173944b3c53SLeonard Chan INTERCEPTOR_ALIAS(uptr, malloc_usable_size, const void *ptr); 174944b3c53SLeonard Chan INTERCEPTOR_ALIAS(void *, calloc, SIZE_T nmemb, SIZE_T size); 175944b3c53SLeonard Chan INTERCEPTOR_ALIAS(void *, realloc, void *ptr, SIZE_T size); 176944b3c53SLeonard Chan INTERCEPTOR_ALIAS(void *, reallocarray, void *ptr, SIZE_T nmemb, SIZE_T size); 177944b3c53SLeonard Chan INTERCEPTOR_ALIAS(void *, malloc, SIZE_T size); 178944b3c53SLeonard Chan 179944b3c53SLeonard Chan # if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 180944b3c53SLeonard Chan INTERCEPTOR_ALIAS(void *, memalign, SIZE_T alignment, SIZE_T size); 181944b3c53SLeonard Chan INTERCEPTOR_ALIAS(void *, pvalloc, SIZE_T size); 182944b3c53SLeonard Chan INTERCEPTOR_ALIAS(void, cfree, void *ptr); 1838f86c6bfSNAKAMURA Takumi INTERCEPTOR_ALIAS(__sanitizer_struct_mallinfo, mallinfo,); 184944b3c53SLeonard Chan INTERCEPTOR_ALIAS(int, mallopt, int cmd, int value); 185944b3c53SLeonard Chan INTERCEPTOR_ALIAS(void, malloc_stats, void); 186944b3c53SLeonard Chan # endif 187c5c67814SLeonard Chan #endif // #if HWASAN_WITH_INTERCEPTORS 188