1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifdef HOOK_ENABLE
17 #include <unistd.h>
18 #include <sys/types.h>
19 #include "musl_malloc.h"
20 #include <malloc.h>
21 #include "musl_malloc_dispatch_table.h"
22 #include "common_def.h"
23 #include "musl_preinit_common.h"
24 #include "signal.h"
25 #ifdef OHOS_FDTRACK_HOOK_ENABLE
26 #include "musl_fdtrack.h"
27 #endif
28
29 #define MALLOC_REPORT_LIMIT (300 * 1024 * 1024)
30
31 #ifdef USE_GWP_ASAN
32 extern void* libc_gwp_asan_malloc(size_t bytes);
33 extern void libc_gwp_asan_free(void *mem);
34 extern size_t libc_gwp_asan_malloc_usable_size(void *mem);
35 extern void* libc_gwp_asan_realloc(void *ptr, size_t size);
36 extern void* libc_gwp_asan_calloc(size_t nmemb, size_t size);
37 #endif
38
39 #ifdef OHOS_FDTRACK_HOOK_ENABLE
40 struct timeval prevTime = {0, 0};
41 static int KICK_ALLOCATE_MEMORY = 60;
42 #endif
43
malloc(size_t bytes)44 void* malloc(size_t bytes)
45 {
46 if (bytes >= MALLOC_REPORT_LIMIT) {
47 #ifdef OHOS_FDTRACK_HOOK_ENABLE
48 if (check_before_memory_allocate(prevTime, KICK_ALLOCATE_MEMORY)) {
49 gettimeofday(&prevTime, NULL);
50 raise(MUSL_SIGNAL_LEAK_STACK);
51 }
52 #endif
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->malloc(bytes);
59 }
60 if (!__get_global_hook_flag()) {
61 #ifdef USE_GWP_ASAN
62 return libc_gwp_asan_malloc(bytes);
63 #endif
64 return MuslFunc(malloc)(bytes);
65 }
66 else if (!__get_hook_flag()) {
67 #ifdef USE_GWP_ASAN
68 return libc_gwp_asan_malloc(bytes);
69 #endif
70 return MuslFunc(malloc)(bytes);
71 }
72 return dispatch_table->malloc(bytes);
73 }
74 #ifdef USE_GWP_ASAN
75 return libc_gwp_asan_malloc(bytes);
76 #endif
77 return MuslFunc(malloc)(bytes);
78 }
79
aligned_alloc(size_t align, size_t len)80 void* aligned_alloc(size_t align, size_t len)
81 {
82 volatile const struct MallocDispatchType* dispatch_table = (struct MallocDispatchType *)atomic_load_explicit(
83 &__musl_libc_globals.current_dispatch_table, memory_order_acquire);
84 if (__predict_false(dispatch_table != NULL)) {
85 if (__get_memleak_hook_flag()) {
86 return dispatch_table->aligned_alloc(align, len);
87 }
88 if (!__get_global_hook_flag()) {
89 return MuslMalloc(aligned_alloc)(align, len);
90 }
91 else if (!__get_hook_flag()) {
92 return MuslMalloc(aligned_alloc)(align, len);
93 }
94 return dispatch_table->aligned_alloc(align, len);
95 }
96 return MuslMalloc(aligned_alloc)(align, len);
97 }
98
free(void* mem)99 void free(void* mem)
100 {
101 volatile const struct MallocDispatchType* dispatch_table = (struct MallocDispatchType *)atomic_load_explicit(
102 &__musl_libc_globals.current_dispatch_table, memory_order_acquire);
103 if (__predict_false(dispatch_table != NULL)) {
104 if (__get_memleak_hook_flag()) {
105 dispatch_table->free(mem);
106 return;
107 }
108 if (!__get_global_hook_flag()) {
109 #ifdef USE_GWP_ASAN
110 return libc_gwp_asan_free(mem);
111 #endif
112 MuslFunc(free)(mem);
113 return;
114 }
115 else if (!__get_hook_flag()) {
116 #ifdef USE_GWP_ASAN
117 return libc_gwp_asan_free(mem);
118 #endif
119 MuslFunc(free)(mem);
120 return;
121 }
122 dispatch_table->free(mem);
123 return;
124 }
125 #ifdef USE_GWP_ASAN
126 return libc_gwp_asan_free(mem);
127 #endif
128 MuslFunc(free)(mem);
129 }
130
mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset)131 void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset)
132 {
133 volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
134 if (__predict_false(dispatch_table != NULL)) {
135 return dispatch_table->mmap(addr, length, prot, flags, fd, offset);
136 } else {
137 return MuslMalloc(mmap)(addr, length, prot, flags, fd, offset);
138 }
139 }
140
munmap(void* addr, size_t length)141 int munmap(void* addr, size_t length)
142 {
143 volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
144 if (__predict_false(dispatch_table != NULL)) {
145 return dispatch_table->munmap(addr, length);
146 } else {
147 return MuslMalloc(munmap)(addr, length);
148 }
149 }
150
calloc(size_t m, size_t n)151 void* calloc(size_t m, size_t n)
152 {
153 if ((m <= (UINT32_MAX / n)) && ((m * n) >= MALLOC_REPORT_LIMIT)) {
154 #ifdef OHOS_FDTRACK_HOOK_ENABLE
155 if (check_before_memory_allocate(prevTime, KICK_ALLOCATE_MEMORY)) {
156 gettimeofday(&prevTime, NULL);
157 raise(MUSL_SIGNAL_LEAK_STACK);
158 }
159 #endif
160 }
161 volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
162 if (__predict_false(dispatch_table != NULL)) {
163 return dispatch_table->calloc(m, n);
164 } else {
165 #ifdef USE_GWP_ASAN
166 return libc_gwp_asan_calloc(m, n);
167 #endif
168 return MuslFunc(calloc)(m, n);
169 }
170 }
171
realloc(void *p, size_t n)172 void* realloc(void *p, size_t n)
173 {
174 if (n >= MALLOC_REPORT_LIMIT) {
175 #ifdef OHOS_FDTRACK_HOOK_ENABLE
176 if (check_before_memory_allocate(prevTime, KICK_ALLOCATE_MEMORY)) {
177 gettimeofday(&prevTime, NULL);
178 raise(MUSL_SIGNAL_LEAK_STACK);
179 }
180 #endif
181 }
182 volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
183 if (__predict_false(dispatch_table != NULL)) {
184 return dispatch_table->realloc(p, n);
185 } else {
186 #ifdef USE_GWP_ASAN
187 return libc_gwp_asan_realloc(p, n);
188 #endif
189 return MuslFunc(realloc)(p, n);
190 }
191 }
192
malloc_usable_size(void* addr)193 size_t malloc_usable_size(void* addr)
194 {
195 volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
196 if (__predict_false(dispatch_table != NULL)) {
197 return dispatch_table->malloc_usable_size(addr);
198 } else {
199 #ifdef USE_GWP_ASAN
200 return libc_gwp_asan_malloc_usable_size(addr);
201 #endif
202 return MuslMalloc(malloc_usable_size)(addr);
203 }
204 }
205
prctl(int option, ...)206 int prctl(int option, ...)
207 {
208 unsigned long x[4];
209 int i;
210 va_list ap;
211 va_start(ap, option);
212 for (i=0; i<4; i++) x[i] = va_arg(ap, unsigned long);
213 va_end(ap);
214 volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
215 if (__predict_false(dispatch_table != NULL)) {
216 return dispatch_table->prctl(option, x[0], x[1], x[2], x[3]);
217 } else {
218 return MuslMalloc(prctl)(option, x[0], x[1], x[2], x[3]);
219 }
220 }
221
222 #endif
223