asan_malloc_linux.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. //===-- asan_malloc_linux.cpp ---------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file is a part of AddressSanitizer, an address sanity checker.
  10. //
  11. // Linux-specific malloc interception.
  12. // We simply define functions like malloc, free, realloc, etc.
  13. // They will replace the corresponding libc functions automagically.
  14. //===----------------------------------------------------------------------===//
  15. #include "sanitizer_common/sanitizer_platform.h"
  16. #if SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || \
  17. SANITIZER_NETBSD || SANITIZER_SOLARIS
  18. # include "asan_allocator.h"
  19. # include "asan_interceptors.h"
  20. # include "asan_internal.h"
  21. # include "asan_stack.h"
  22. # include "lsan/lsan_common.h"
  23. # include "sanitizer_common/sanitizer_allocator_checks.h"
  24. # include "sanitizer_common/sanitizer_allocator_dlsym.h"
  25. # include "sanitizer_common/sanitizer_errno.h"
  26. # include "sanitizer_common/sanitizer_tls_get_addr.h"
  27. // ---------------------- Replacement functions ---------------- {{{1
  28. using namespace __asan;
  29. struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
  30. static bool UseImpl() { return asan_init_is_running; }
  31. static void OnAllocate(const void *ptr, uptr size) {
  32. # if CAN_SANITIZE_LEAKS
  33. // Suppress leaks from dlerror(). Previously dlsym hack on global array was
  34. // used by leak sanitizer as a root region.
  35. __lsan_register_root_region(ptr, size);
  36. # endif
  37. }
  38. static void OnFree(const void *ptr, uptr size) {
  39. # if CAN_SANITIZE_LEAKS
  40. __lsan_unregister_root_region(ptr, size);
  41. # endif
  42. }
  43. };
  44. INTERCEPTOR(void, free, void *ptr) {
  45. if (DlsymAlloc::PointerIsMine(ptr))
  46. return DlsymAlloc::Free(ptr);
  47. GET_STACK_TRACE_FREE;
  48. asan_free(ptr, &stack, FROM_MALLOC);
  49. }
  50. #if SANITIZER_INTERCEPT_CFREE
  51. INTERCEPTOR(void, cfree, void *ptr) {
  52. if (DlsymAlloc::PointerIsMine(ptr))
  53. return DlsymAlloc::Free(ptr);
  54. GET_STACK_TRACE_FREE;
  55. asan_free(ptr, &stack, FROM_MALLOC);
  56. }
  57. #endif // SANITIZER_INTERCEPT_CFREE
  58. INTERCEPTOR(void*, malloc, uptr size) {
  59. if (DlsymAlloc::Use())
  60. return DlsymAlloc::Allocate(size);
  61. ENSURE_ASAN_INITED();
  62. GET_STACK_TRACE_MALLOC;
  63. return asan_malloc(size, &stack);
  64. }
  65. INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
  66. if (DlsymAlloc::Use())
  67. return DlsymAlloc::Callocate(nmemb, size);
  68. ENSURE_ASAN_INITED();
  69. GET_STACK_TRACE_MALLOC;
  70. return asan_calloc(nmemb, size, &stack);
  71. }
  72. INTERCEPTOR(void*, realloc, void *ptr, uptr size) {
  73. if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
  74. return DlsymAlloc::Realloc(ptr, size);
  75. ENSURE_ASAN_INITED();
  76. GET_STACK_TRACE_MALLOC;
  77. return asan_realloc(ptr, size, &stack);
  78. }
  79. #if SANITIZER_INTERCEPT_REALLOCARRAY
  80. INTERCEPTOR(void*, reallocarray, void *ptr, uptr nmemb, uptr size) {
  81. ENSURE_ASAN_INITED();
  82. GET_STACK_TRACE_MALLOC;
  83. return asan_reallocarray(ptr, nmemb, size, &stack);
  84. }
  85. #endif // SANITIZER_INTERCEPT_REALLOCARRAY
  86. #if SANITIZER_INTERCEPT_MEMALIGN
  87. INTERCEPTOR(void*, memalign, uptr boundary, uptr size) {
  88. GET_STACK_TRACE_MALLOC;
  89. return asan_memalign(boundary, size, &stack, FROM_MALLOC);
  90. }
  91. INTERCEPTOR(void*, __libc_memalign, uptr boundary, uptr size) {
  92. GET_STACK_TRACE_MALLOC;
  93. void *res = asan_memalign(boundary, size, &stack, FROM_MALLOC);
  94. DTLS_on_libc_memalign(res, size);
  95. return res;
  96. }
  97. #endif // SANITIZER_INTERCEPT_MEMALIGN
  98. #if SANITIZER_INTERCEPT_ALIGNED_ALLOC
  99. INTERCEPTOR(void*, aligned_alloc, uptr boundary, uptr size) {
  100. GET_STACK_TRACE_MALLOC;
  101. return asan_aligned_alloc(boundary, size, &stack);
  102. }
  103. #endif // SANITIZER_INTERCEPT_ALIGNED_ALLOC
  104. INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
  105. GET_CURRENT_PC_BP_SP;
  106. (void)sp;
  107. return asan_malloc_usable_size(ptr, pc, bp);
  108. }
  109. #if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
  110. // We avoid including malloc.h for portability reasons.
  111. // man mallinfo says the fields are "long", but the implementation uses int.
  112. // It doesn't matter much -- we just need to make sure that the libc's mallinfo
  113. // is not called.
  114. struct fake_mallinfo {
  115. int x[10];
  116. };
  117. INTERCEPTOR(struct fake_mallinfo, mallinfo, void) {
  118. struct fake_mallinfo res;
  119. REAL(memset)(&res, 0, sizeof(res));
  120. return res;
  121. }
  122. INTERCEPTOR(int, mallopt, int cmd, int value) {
  123. return 0;
  124. }
  125. #endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
  126. INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {
  127. GET_STACK_TRACE_MALLOC;
  128. return asan_posix_memalign(memptr, alignment, size, &stack);
  129. }
  130. INTERCEPTOR(void*, valloc, uptr size) {
  131. GET_STACK_TRACE_MALLOC;
  132. return asan_valloc(size, &stack);
  133. }
  134. #if SANITIZER_INTERCEPT_PVALLOC
  135. INTERCEPTOR(void*, pvalloc, uptr size) {
  136. GET_STACK_TRACE_MALLOC;
  137. return asan_pvalloc(size, &stack);
  138. }
  139. #endif // SANITIZER_INTERCEPT_PVALLOC
  140. INTERCEPTOR(void, malloc_stats, void) {
  141. __asan_print_accumulated_stats();
  142. }
  143. #if SANITIZER_ANDROID
  144. // Format of __libc_malloc_dispatch has changed in Android L.
  145. // While we are moving towards a solution that does not depend on bionic
  146. // internals, here is something to support both K* and L releases.
  147. struct MallocDebugK {
  148. void *(*malloc)(uptr bytes);
  149. void (*free)(void *mem);
  150. void *(*calloc)(uptr n_elements, uptr elem_size);
  151. void *(*realloc)(void *oldMem, uptr bytes);
  152. void *(*memalign)(uptr alignment, uptr bytes);
  153. uptr (*malloc_usable_size)(void *mem);
  154. };
  155. struct MallocDebugL {
  156. void *(*calloc)(uptr n_elements, uptr elem_size);
  157. void (*free)(void *mem);
  158. fake_mallinfo (*mallinfo)(void);
  159. void *(*malloc)(uptr bytes);
  160. uptr (*malloc_usable_size)(void *mem);
  161. void *(*memalign)(uptr alignment, uptr bytes);
  162. int (*posix_memalign)(void **memptr, uptr alignment, uptr size);
  163. void* (*pvalloc)(uptr size);
  164. void *(*realloc)(void *oldMem, uptr bytes);
  165. void* (*valloc)(uptr size);
  166. };
  167. ALIGNED(32) const MallocDebugK asan_malloc_dispatch_k = {
  168. WRAP(malloc), WRAP(free), WRAP(calloc),
  169. WRAP(realloc), WRAP(memalign), WRAP(malloc_usable_size)};
  170. ALIGNED(32) const MallocDebugL asan_malloc_dispatch_l = {
  171. WRAP(calloc), WRAP(free), WRAP(mallinfo),
  172. WRAP(malloc), WRAP(malloc_usable_size), WRAP(memalign),
  173. WRAP(posix_memalign), WRAP(pvalloc), WRAP(realloc),
  174. WRAP(valloc)};
  175. namespace __asan {
  176. void ReplaceSystemMalloc() {
  177. void **__libc_malloc_dispatch_p =
  178. (void **)AsanDlSymNext("__libc_malloc_dispatch");
  179. if (__libc_malloc_dispatch_p) {
  180. // Decide on K vs L dispatch format by the presence of
  181. // __libc_malloc_default_dispatch export in libc.
  182. void *default_dispatch_p = AsanDlSymNext("__libc_malloc_default_dispatch");
  183. if (default_dispatch_p)
  184. *__libc_malloc_dispatch_p = (void *)&asan_malloc_dispatch_k;
  185. else
  186. *__libc_malloc_dispatch_p = (void *)&asan_malloc_dispatch_l;
  187. }
  188. }
  189. } // namespace __asan
  190. #else // SANITIZER_ANDROID
  191. namespace __asan {
  192. void ReplaceSystemMalloc() {
  193. }
  194. } // namespace __asan
  195. #endif // SANITIZER_ANDROID
  196. #endif // SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX ||
  197. // SANITIZER_NETBSD || SANITIZER_SOLARIS