xref: /llvm-project/compiler-rt/lib/hwasan/hwasan_allocation_functions.cpp (revision b07f1be92c1350d8d5b0952f49a2c3aeedcccb2f)
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