1570af302Sopenharmony_ci/*
2570af302Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4570af302Sopenharmony_ci * you may not use this file except in compliance with the License.
5570af302Sopenharmony_ci * You may obtain a copy of the License at
6570af302Sopenharmony_ci *
7570af302Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8570af302Sopenharmony_ci *
9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12570af302Sopenharmony_ci * See the License for the specific language governing permissions and
13570af302Sopenharmony_ci * limitations under the License.
14570af302Sopenharmony_ci */
15570af302Sopenharmony_ci
16570af302Sopenharmony_ci#ifdef HOOK_ENABLE
17570af302Sopenharmony_ci#include <unistd.h>
18570af302Sopenharmony_ci#include <sys/types.h>
19570af302Sopenharmony_ci#include "musl_malloc.h"
20570af302Sopenharmony_ci#include <malloc.h>
21570af302Sopenharmony_ci#include "musl_malloc_dispatch_table.h"
22570af302Sopenharmony_ci#include "common_def.h"
23570af302Sopenharmony_ci#include "musl_preinit_common.h"
24570af302Sopenharmony_ci#include "signal.h"
25570af302Sopenharmony_ci#ifdef OHOS_FDTRACK_HOOK_ENABLE
26570af302Sopenharmony_ci#include "musl_fdtrack.h"
27570af302Sopenharmony_ci#endif
28570af302Sopenharmony_ci
29570af302Sopenharmony_ci#define MALLOC_REPORT_LIMIT (300 * 1024 * 1024)
30570af302Sopenharmony_ci
31570af302Sopenharmony_ci#ifdef USE_GWP_ASAN
32570af302Sopenharmony_ciextern void* libc_gwp_asan_malloc(size_t bytes);
33570af302Sopenharmony_ciextern void libc_gwp_asan_free(void *mem);
34570af302Sopenharmony_ciextern size_t libc_gwp_asan_malloc_usable_size(void *mem);
35570af302Sopenharmony_ciextern void* libc_gwp_asan_realloc(void *ptr, size_t size);
36570af302Sopenharmony_ciextern void* libc_gwp_asan_calloc(size_t nmemb, size_t size);
37570af302Sopenharmony_ci#endif
38570af302Sopenharmony_ci
39570af302Sopenharmony_ci#ifdef OHOS_FDTRACK_HOOK_ENABLE
40570af302Sopenharmony_cistruct timeval prevTime = {0, 0};
41570af302Sopenharmony_cistatic int KICK_ALLOCATE_MEMORY = 60;
42570af302Sopenharmony_ci#endif
43570af302Sopenharmony_ci
44570af302Sopenharmony_civoid* malloc(size_t bytes)
45570af302Sopenharmony_ci{
46570af302Sopenharmony_ci	if (bytes >= MALLOC_REPORT_LIMIT) {
47570af302Sopenharmony_ci#ifdef OHOS_FDTRACK_HOOK_ENABLE
48570af302Sopenharmony_ci		if (check_before_memory_allocate(prevTime, KICK_ALLOCATE_MEMORY)) {
49570af302Sopenharmony_ci			gettimeofday(&prevTime, NULL);
50570af302Sopenharmony_ci			raise(MUSL_SIGNAL_LEAK_STACK);
51570af302Sopenharmony_ci		}
52570af302Sopenharmony_ci#endif
53570af302Sopenharmony_ci	}
54570af302Sopenharmony_ci	volatile const struct MallocDispatchType* dispatch_table = (struct MallocDispatchType *)atomic_load_explicit(
55570af302Sopenharmony_ci		&__musl_libc_globals.current_dispatch_table, memory_order_acquire);
56570af302Sopenharmony_ci	if (__predict_false(dispatch_table != NULL)) {
57570af302Sopenharmony_ci		if (__get_memleak_hook_flag()) {
58570af302Sopenharmony_ci			return dispatch_table->malloc(bytes);
59570af302Sopenharmony_ci		}
60570af302Sopenharmony_ci		if (!__get_global_hook_flag()) {
61570af302Sopenharmony_ci#ifdef USE_GWP_ASAN
62570af302Sopenharmony_ci			return libc_gwp_asan_malloc(bytes);
63570af302Sopenharmony_ci#endif
64570af302Sopenharmony_ci			return MuslFunc(malloc)(bytes);
65570af302Sopenharmony_ci		}
66570af302Sopenharmony_ci		else if (!__get_hook_flag()) {
67570af302Sopenharmony_ci#ifdef USE_GWP_ASAN
68570af302Sopenharmony_ci			return libc_gwp_asan_malloc(bytes);
69570af302Sopenharmony_ci#endif
70570af302Sopenharmony_ci			return MuslFunc(malloc)(bytes);
71570af302Sopenharmony_ci		}
72570af302Sopenharmony_ci		return dispatch_table->malloc(bytes);
73570af302Sopenharmony_ci	}
74570af302Sopenharmony_ci#ifdef USE_GWP_ASAN
75570af302Sopenharmony_ci	return libc_gwp_asan_malloc(bytes);
76570af302Sopenharmony_ci#endif
77570af302Sopenharmony_ci	return  MuslFunc(malloc)(bytes);
78570af302Sopenharmony_ci}
79570af302Sopenharmony_ci
80570af302Sopenharmony_civoid* aligned_alloc(size_t align, size_t len)
81570af302Sopenharmony_ci{
82570af302Sopenharmony_ci	volatile const struct MallocDispatchType* dispatch_table = (struct MallocDispatchType *)atomic_load_explicit(
83570af302Sopenharmony_ci		&__musl_libc_globals.current_dispatch_table, memory_order_acquire);
84570af302Sopenharmony_ci	if (__predict_false(dispatch_table != NULL)) {
85570af302Sopenharmony_ci		if (__get_memleak_hook_flag()) {
86570af302Sopenharmony_ci			return dispatch_table->aligned_alloc(align, len);
87570af302Sopenharmony_ci		}
88570af302Sopenharmony_ci		if (!__get_global_hook_flag()) {
89570af302Sopenharmony_ci			return MuslMalloc(aligned_alloc)(align, len);
90570af302Sopenharmony_ci		}
91570af302Sopenharmony_ci		else if (!__get_hook_flag()) {
92570af302Sopenharmony_ci			return MuslMalloc(aligned_alloc)(align, len);
93570af302Sopenharmony_ci		}
94570af302Sopenharmony_ci		return dispatch_table->aligned_alloc(align, len);
95570af302Sopenharmony_ci	}
96570af302Sopenharmony_ci	return  MuslMalloc(aligned_alloc)(align, len);
97570af302Sopenharmony_ci}
98570af302Sopenharmony_ci
99570af302Sopenharmony_civoid free(void* mem)
100570af302Sopenharmony_ci{
101570af302Sopenharmony_ci	volatile const struct MallocDispatchType* dispatch_table = (struct MallocDispatchType *)atomic_load_explicit(
102570af302Sopenharmony_ci		&__musl_libc_globals.current_dispatch_table, memory_order_acquire);
103570af302Sopenharmony_ci	if (__predict_false(dispatch_table != NULL)) {
104570af302Sopenharmony_ci		if (__get_memleak_hook_flag()) {
105570af302Sopenharmony_ci			dispatch_table->free(mem);
106570af302Sopenharmony_ci			return;
107570af302Sopenharmony_ci		}
108570af302Sopenharmony_ci		if (!__get_global_hook_flag()) {
109570af302Sopenharmony_ci#ifdef USE_GWP_ASAN
110570af302Sopenharmony_ci			return libc_gwp_asan_free(mem);
111570af302Sopenharmony_ci#endif
112570af302Sopenharmony_ci			MuslFunc(free)(mem);
113570af302Sopenharmony_ci			return;
114570af302Sopenharmony_ci		}
115570af302Sopenharmony_ci		else if (!__get_hook_flag()) {
116570af302Sopenharmony_ci#ifdef USE_GWP_ASAN
117570af302Sopenharmony_ci			return libc_gwp_asan_free(mem);
118570af302Sopenharmony_ci#endif
119570af302Sopenharmony_ci			MuslFunc(free)(mem);
120570af302Sopenharmony_ci			return;
121570af302Sopenharmony_ci		}
122570af302Sopenharmony_ci		dispatch_table->free(mem);
123570af302Sopenharmony_ci		return;
124570af302Sopenharmony_ci	}
125570af302Sopenharmony_ci#ifdef USE_GWP_ASAN
126570af302Sopenharmony_ci	return libc_gwp_asan_free(mem);
127570af302Sopenharmony_ci#endif
128570af302Sopenharmony_ci	MuslFunc(free)(mem);
129570af302Sopenharmony_ci}
130570af302Sopenharmony_ci
131570af302Sopenharmony_civoid* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset)
132570af302Sopenharmony_ci{
133570af302Sopenharmony_ci	volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
134570af302Sopenharmony_ci	if (__predict_false(dispatch_table != NULL)) {
135570af302Sopenharmony_ci		return dispatch_table->mmap(addr, length, prot, flags, fd, offset);
136570af302Sopenharmony_ci	} else {
137570af302Sopenharmony_ci		return MuslMalloc(mmap)(addr, length, prot, flags, fd, offset);
138570af302Sopenharmony_ci	}
139570af302Sopenharmony_ci}
140570af302Sopenharmony_ci
141570af302Sopenharmony_ciint munmap(void* addr, size_t length)
142570af302Sopenharmony_ci{
143570af302Sopenharmony_ci	volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
144570af302Sopenharmony_ci	if (__predict_false(dispatch_table != NULL)) {
145570af302Sopenharmony_ci		return dispatch_table->munmap(addr, length);
146570af302Sopenharmony_ci	} else {
147570af302Sopenharmony_ci		return MuslMalloc(munmap)(addr, length);
148570af302Sopenharmony_ci	}
149570af302Sopenharmony_ci}
150570af302Sopenharmony_ci
151570af302Sopenharmony_civoid* calloc(size_t m, size_t n)
152570af302Sopenharmony_ci{
153570af302Sopenharmony_ci	if ((m <= (UINT32_MAX / n)) && ((m * n) >= MALLOC_REPORT_LIMIT)) {
154570af302Sopenharmony_ci#ifdef OHOS_FDTRACK_HOOK_ENABLE
155570af302Sopenharmony_ci		if (check_before_memory_allocate(prevTime, KICK_ALLOCATE_MEMORY)) {
156570af302Sopenharmony_ci			gettimeofday(&prevTime, NULL);
157570af302Sopenharmony_ci			raise(MUSL_SIGNAL_LEAK_STACK);
158570af302Sopenharmony_ci		}
159570af302Sopenharmony_ci#endif
160570af302Sopenharmony_ci	}
161570af302Sopenharmony_ci	volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
162570af302Sopenharmony_ci	if (__predict_false(dispatch_table != NULL)) {
163570af302Sopenharmony_ci		return dispatch_table->calloc(m, n);
164570af302Sopenharmony_ci	} else {
165570af302Sopenharmony_ci#ifdef USE_GWP_ASAN
166570af302Sopenharmony_ci		return libc_gwp_asan_calloc(m, n);
167570af302Sopenharmony_ci#endif
168570af302Sopenharmony_ci		return MuslFunc(calloc)(m, n);
169570af302Sopenharmony_ci	}
170570af302Sopenharmony_ci}
171570af302Sopenharmony_ci
172570af302Sopenharmony_civoid* realloc(void *p, size_t n)
173570af302Sopenharmony_ci{
174570af302Sopenharmony_ci	if (n >= MALLOC_REPORT_LIMIT) {
175570af302Sopenharmony_ci#ifdef OHOS_FDTRACK_HOOK_ENABLE
176570af302Sopenharmony_ci		if (check_before_memory_allocate(prevTime, KICK_ALLOCATE_MEMORY)) {
177570af302Sopenharmony_ci			gettimeofday(&prevTime, NULL);
178570af302Sopenharmony_ci			raise(MUSL_SIGNAL_LEAK_STACK);
179570af302Sopenharmony_ci		}
180570af302Sopenharmony_ci#endif
181570af302Sopenharmony_ci	}
182570af302Sopenharmony_ci	volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
183570af302Sopenharmony_ci	if (__predict_false(dispatch_table != NULL)) {
184570af302Sopenharmony_ci		return dispatch_table->realloc(p, n);
185570af302Sopenharmony_ci	} else {
186570af302Sopenharmony_ci#ifdef USE_GWP_ASAN
187570af302Sopenharmony_ci		return libc_gwp_asan_realloc(p, n);
188570af302Sopenharmony_ci#endif
189570af302Sopenharmony_ci		return MuslFunc(realloc)(p, n);
190570af302Sopenharmony_ci	}
191570af302Sopenharmony_ci}
192570af302Sopenharmony_ci
193570af302Sopenharmony_cisize_t malloc_usable_size(void* addr)
194570af302Sopenharmony_ci{
195570af302Sopenharmony_ci	volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
196570af302Sopenharmony_ci	if (__predict_false(dispatch_table != NULL)) {
197570af302Sopenharmony_ci		return dispatch_table->malloc_usable_size(addr);
198570af302Sopenharmony_ci	} else {
199570af302Sopenharmony_ci#ifdef USE_GWP_ASAN
200570af302Sopenharmony_ci		return libc_gwp_asan_malloc_usable_size(addr);
201570af302Sopenharmony_ci#endif
202570af302Sopenharmony_ci		return MuslMalloc(malloc_usable_size)(addr);
203570af302Sopenharmony_ci	}
204570af302Sopenharmony_ci}
205570af302Sopenharmony_ci
206570af302Sopenharmony_ciint prctl(int option, ...)
207570af302Sopenharmony_ci{
208570af302Sopenharmony_ci	unsigned long x[4];
209570af302Sopenharmony_ci	int i;
210570af302Sopenharmony_ci	va_list ap;
211570af302Sopenharmony_ci	va_start(ap, option);
212570af302Sopenharmony_ci	for (i=0; i<4; i++) x[i] = va_arg(ap, unsigned long);
213570af302Sopenharmony_ci	va_end(ap);
214570af302Sopenharmony_ci	volatile const struct MallocDispatchType* dispatch_table = get_current_dispatch_table();
215570af302Sopenharmony_ci	if (__predict_false(dispatch_table != NULL)) {
216570af302Sopenharmony_ci		return dispatch_table->prctl(option, x[0], x[1], x[2], x[3]);
217570af302Sopenharmony_ci	} else {
218570af302Sopenharmony_ci		return MuslMalloc(prctl)(option, x[0], x[1], x[2], x[3]);
219570af302Sopenharmony_ci	}
220570af302Sopenharmony_ci}
221570af302Sopenharmony_ci
222570af302Sopenharmony_ci#endif
223