188 lines · cpp
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-exception6//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 21using namespace __hwasan;22 23struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {24 static bool UseImpl() { return !hwasan_inited; }25 static void OnAllocate(const void *ptr, uptr size) {26# if CAN_SANITIZE_LEAKS27 // Suppress leaks from dlerror(). Previously dlsym hack on global array was28 // used by leak sanitizer as a root region.29 __lsan_register_root_region(ptr, size);30# endif31 }32 static void OnFree(const void *ptr, uptr size) {33# if CAN_SANITIZE_LEAKS34 __lsan_unregister_root_region(ptr, size);35# endif36 }37};38 39extern "C" {40 41SANITIZER_INTERFACE_ATTRIBUTE42int __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 49SANITIZER_INTERFACE_ATTRIBUTE50void *__sanitizer_memalign(uptr alignment, uptr size) {51 GET_MALLOC_STACK_TRACE;52 return hwasan_memalign(alignment, size, &stack);53}54 55SANITIZER_INTERFACE_ATTRIBUTE56void *__sanitizer_aligned_alloc(uptr alignment, uptr size) {57 GET_MALLOC_STACK_TRACE;58 return hwasan_aligned_alloc(alignment, size, &stack);59}60 61SANITIZER_INTERFACE_ATTRIBUTE62void *__sanitizer___libc_memalign(uptr alignment, uptr size) {63 GET_MALLOC_STACK_TRACE;64 return hwasan_memalign(alignment, size, &stack);65}66 67SANITIZER_INTERFACE_ATTRIBUTE68void *__sanitizer_valloc(uptr size) {69 GET_MALLOC_STACK_TRACE;70 return hwasan_valloc(size, &stack);71}72 73SANITIZER_INTERFACE_ATTRIBUTE74void *__sanitizer_pvalloc(uptr size) {75 GET_MALLOC_STACK_TRACE;76 return hwasan_pvalloc(size, &stack);77}78 79SANITIZER_INTERFACE_ATTRIBUTE80void __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 89SANITIZER_INTERFACE_ATTRIBUTE90void __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 99SANITIZER_INTERFACE_ATTRIBUTE100uptr __sanitizer_malloc_usable_size(const void *ptr) {101 return __sanitizer_get_allocated_size(ptr);102}103 104SANITIZER_INTERFACE_ATTRIBUTE105struct __sanitizer_struct_mallinfo __sanitizer_mallinfo() {106 __sanitizer_struct_mallinfo sret;107 internal_memset(&sret, 0, sizeof(sret));108 return sret;109}110 111SANITIZER_INTERFACE_ATTRIBUTE112int __sanitizer_mallopt(int cmd, int value) { return 0; }113 114SANITIZER_INTERFACE_ATTRIBUTE115void __sanitizer_malloc_stats(void) {116 // FIXME: implement, but don't call REAL(malloc_stats)!117}118 119SANITIZER_INTERFACE_ATTRIBUTE120void *__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 127SANITIZER_INTERFACE_ATTRIBUTE128void *__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 135SANITIZER_INTERFACE_ATTRIBUTE136void *__sanitizer_reallocarray(void *ptr, uptr nmemb, uptr size) {137 GET_MALLOC_STACK_TRACE;138 return hwasan_reallocarray(ptr, nmemb, size, &stack);139}140 141SANITIZER_INTERFACE_ATTRIBUTE142void *__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_FUCHSIA154#if SANITIZER_FUCHSIA155// 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#else160# 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#endif166 167INTERCEPTOR_ALIAS(int, posix_memalign, void **memptr, SIZE_T alignment,168 SIZE_T size);169INTERCEPTOR_ALIAS(void *, aligned_alloc, SIZE_T alignment, SIZE_T size);170INTERCEPTOR_ALIAS(void *, __libc_memalign, SIZE_T alignment, SIZE_T size);171INTERCEPTOR_ALIAS(void *, valloc, SIZE_T size);172INTERCEPTOR_ALIAS(void, free, void *ptr);173INTERCEPTOR_ALIAS(uptr, malloc_usable_size, const void *ptr);174INTERCEPTOR_ALIAS(void *, calloc, SIZE_T nmemb, SIZE_T size);175INTERCEPTOR_ALIAS(void *, realloc, void *ptr, SIZE_T size);176INTERCEPTOR_ALIAS(void *, reallocarray, void *ptr, SIZE_T nmemb, SIZE_T size);177INTERCEPTOR_ALIAS(void *, malloc, SIZE_T size);178 179# if !SANITIZER_FREEBSD && !SANITIZER_NETBSD180INTERCEPTOR_ALIAS(void *, memalign, SIZE_T alignment, SIZE_T size);181INTERCEPTOR_ALIAS(void *, pvalloc, SIZE_T size);182INTERCEPTOR_ALIAS(void, cfree, void *ptr);183INTERCEPTOR_ALIAS(__sanitizer_struct_mallinfo, mallinfo,);184INTERCEPTOR_ALIAS(int, mallopt, int cmd, int value);185INTERCEPTOR_ALIAS(void, malloc_stats, void);186# endif187#endif // #if HWASAN_WITH_INTERCEPTORS188