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 32extern void* libc_gwp_asan_malloc(size_t bytes); 33extern void libc_gwp_asan_free(void *mem); 34extern size_t libc_gwp_asan_malloc_usable_size(void *mem); 35extern void* libc_gwp_asan_realloc(void *ptr, size_t size); 36extern void* libc_gwp_asan_calloc(size_t nmemb, size_t size); 37#endif 38 39#ifdef OHOS_FDTRACK_HOOK_ENABLE 40struct timeval prevTime = {0, 0}; 41static int KICK_ALLOCATE_MEMORY = 60; 42#endif 43 44void* 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 80void* 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 99void 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 131void* 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 141int 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 151void* 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 172void* 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 193size_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 206int 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