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