1 #ifdef HOOK_ENABLE
2 #include <unistd.h>
3 #include <sys/types.h>
4 #include "musl_malloc.h"
5 #include <malloc.h>
6 #include "musl_malloc_dispatch_table.h"
7 #include "common_def.h"
8 #include "musl_preinit_common.h"
9 #include "signal.h"
10
11 #define MALLOC_REPORT_LIMIT (300 * 1024 * 1024)
12
13 #ifdef USE_GWP_ASAN
14 extern void* libc_gwp_asan_malloc(size_t bytes);
15 extern void libc_gwp_asan_free(void *mem);
16 extern size_t libc_gwp_asan_malloc_usable_size(void *mem);
17 extern void* libc_gwp_asan_realloc(void *ptr, size_t size);
18 extern void* libc_gwp_asan_calloc(size_t nmemb, size_t size);
19 #endif
20
malloc(size_t bytes)21 void* malloc(size_t bytes)
22 {
23 if (bytes >= MALLOC_REPORT_LIMIT) {
24 raise(MUSL_SIGNAL_LEAK_STACK);
25 }
26 volatile const struct MallocDispatchType* dispatch_table = (struct MallocDispatchType *)atomic_load_explicit(
27 &__musl_libc_globals.current_dispatch_table, memory_order_acquire);
28 if (__predict_false(dispatch_table != NULL)) {
29 if (__get_memleak_hook_flag()) {
30 return dispatch_table->malloc(bytes);
31 }
32 if (!__get_global_hook_flag()) {
33 #ifdef USE_GWP_ASAN
34 return libc_gwp_asan_malloc(bytes);
35 #endif
36 return MuslFunc(malloc)(bytes);
37 }
38 else if (!__get_hook_flag()) {
39 #ifdef USE_GWP_ASAN
40 return libc_gwp_asan_malloc(bytes);
41 #endif
42 return MuslFunc(malloc)(bytes);
43 }
44 return dispatch_table->malloc(bytes);
45 }
46 #ifdef USE_GWP_ASAN
47 return libc_gwp_asan_malloc(bytes);
48 #endif
49 return MuslFunc(malloc)(bytes);
50 }
51
aligned_alloc(size_t align, size_t len)52 void* aligned_alloc(size_t align, size_t len)
53 {
54 volatile const struct MallocDispatchType* dispatch_table = (struct MallocDispatchType *)atomic_load_explicit(
55 &__musl_libc_globals.current_dispatch_table, memory_order_acquire);
56 if (__predict_false(dispatch_table != NULL)) {
57 if (__get_memleak_hook_flag()) {
58 return dispatch_table->aligned_alloc(align, len);
59 }
60 if (!__get_global_hook_flag()) {
61 return MuslMalloc(aligned_alloc)(align, len);
62 }
63 else if (!__get_hook_flag()) {
64 return MuslMalloc(aligned_alloc)(align, len);
65 }
66 return dispatch_table->aligned_alloc(align, len);
67 }
68 return MuslMalloc(aligned_alloc)(align, len);
69 }
70
free(void* mem)71 void free(void* mem)
72 {
73 volatile const struct MallocDispatchType* dispatch_table = (struct MallocDispatchType *)atomic_load_explicit(
74 &__musl_libc_globals.current_dispatch_table, memory_order_acquire);
75 if (__predict_false(dispatch_table != NULL)) {
76 if (__get_memleak_hook_flag()) {
77 dispatch_table->free(mem);
78 return;
79 }
80 if (!__get_global_hook_flag()) {
81 #ifdef USE_GWP_ASAN
82 return libc_gwp_asan_free(mem);
83 #endif
84 MuslFunc(free)(mem);
85 return;
86 }
87 else if (!__get_hook_flag()) {
88 #ifdef USE_GWP_ASAN
89 return libc_gwp_asan_free(mem);
90 #endif
91 MuslFunc(free)(mem);
92 return;
93 }
94 dispatch_table->free(mem);
95 return;
96 }
97 #ifdef USE_GWP_ASAN
98 return libc_gwp_asan_free(mem);
99 #endif
100 MuslFunc(free)(mem);
101 }
102
mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset)103 void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset)
104 {
105 volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
106 if (__predict_false(dispatch_table != NULL)) {
107 return dispatch_table->mmap(addr, length, prot, flags, fd, offset);
108 } else {
109 return MuslMalloc(mmap)(addr, length, prot, flags, fd, offset);
110 }
111 }
112
munmap(void* addr, size_t length)113 int munmap(void* addr, size_t length)
114 {
115 volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
116 if (__predict_false(dispatch_table != NULL)) {
117 return dispatch_table->munmap(addr, length);
118 } else {
119 return MuslMalloc(munmap)(addr, length);
120 }
121 }
122
calloc(size_t m, size_t n)123 void* calloc(size_t m, size_t n)
124 {
125 if ((m <= (UINT32_MAX / n)) && ((m * n) >= MALLOC_REPORT_LIMIT)) {
126 raise(MUSL_SIGNAL_LEAK_STACK);
127 }
128 volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
129 if (__predict_false(dispatch_table != NULL)) {
130 return dispatch_table->calloc(m, n);
131 } else {
132 #ifdef USE_GWP_ASAN
133 return libc_gwp_asan_calloc(m, n);
134 #endif
135 return MuslFunc(calloc)(m, n);
136 }
137 }
138
realloc(void *p, size_t n)139 void* realloc(void *p, size_t n)
140 {
141 if (n >= MALLOC_REPORT_LIMIT) {
142 raise(MUSL_SIGNAL_LEAK_STACK);
143 }
144 volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
145 if (__predict_false(dispatch_table != NULL)) {
146 return dispatch_table->realloc(p, n);
147 } else {
148 #ifdef USE_GWP_ASAN
149 return libc_gwp_asan_realloc(p, n);
150 #endif
151 return MuslFunc(realloc)(p, n);
152 }
153 }
154
malloc_usable_size(void* addr)155 size_t malloc_usable_size(void* addr)
156 {
157 volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
158 if (__predict_false(dispatch_table != NULL)) {
159 return dispatch_table->malloc_usable_size(addr);
160 } else {
161 #ifdef USE_GWP_ASAN
162 return libc_gwp_asan_malloc_usable_size(addr);
163 #endif
164 return MuslMalloc(malloc_usable_size)(addr);
165 }
166 }
167
prctl(int option, ...)168 int prctl(int option, ...)
169 {
170 unsigned long x[4];
171 int i;
172 va_list ap;
173 va_start(ap, option);
174 for (i=0; i<4; i++) x[i] = va_arg(ap, unsigned long);
175 va_end(ap);
176 volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
177 if (__predict_false(dispatch_table != NULL)) {
178 return dispatch_table->prctl(option, x[0], x[1], x[2], x[3]);
179 } else {
180 return MuslMalloc(prctl)(option, x[0], x[1], x[2], x[3]);
181 }
182 }
183
184 #endif
185