asan_malloc_linux.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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 !TryAsanInitFromRtl(); }
  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. GET_STACK_TRACE_MALLOC;
  62. return asan_malloc(size, &stack);
  63. }
  64. INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
  65. if (DlsymAlloc::Use())
  66. return DlsymAlloc::Callocate(nmemb, size);
  67. GET_STACK_TRACE_MALLOC;
  68. return asan_calloc(nmemb, size, &stack);
  69. }
  70. INTERCEPTOR(void*, realloc, void *ptr, uptr size) {
  71. if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
  72. return DlsymAlloc::Realloc(ptr, size);
  73. GET_STACK_TRACE_MALLOC;
  74. return asan_realloc(ptr, size, &stack);
  75. }
  76. #if SANITIZER_INTERCEPT_REALLOCARRAY
  77. INTERCEPTOR(void*, reallocarray, void *ptr, uptr nmemb, uptr size) {
  78. AsanInitFromRtl();
  79. GET_STACK_TRACE_MALLOC;
  80. return asan_reallocarray(ptr, nmemb, size, &stack);
  81. }
  82. #endif // SANITIZER_INTERCEPT_REALLOCARRAY
  83. #if SANITIZER_INTERCEPT_MEMALIGN
  84. INTERCEPTOR(void*, memalign, uptr boundary, uptr size) {
  85. GET_STACK_TRACE_MALLOC;
  86. return asan_memalign(boundary, size, &stack, FROM_MALLOC);
  87. }
  88. INTERCEPTOR(void*, __libc_memalign, uptr boundary, uptr size) {
  89. GET_STACK_TRACE_MALLOC;
  90. void *res = asan_memalign(boundary, size, &stack, FROM_MALLOC);
  91. DTLS_on_libc_memalign(res, size);
  92. return res;
  93. }
  94. #endif // SANITIZER_INTERCEPT_MEMALIGN
  95. #if SANITIZER_INTERCEPT_ALIGNED_ALLOC
  96. INTERCEPTOR(void*, aligned_alloc, uptr boundary, uptr size) {
  97. GET_STACK_TRACE_MALLOC;
  98. return asan_aligned_alloc(boundary, size, &stack);
  99. }
  100. #endif // SANITIZER_INTERCEPT_ALIGNED_ALLOC
  101. INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
  102. GET_CURRENT_PC_BP_SP;
  103. (void)sp;
  104. return asan_malloc_usable_size(ptr, pc, bp);
  105. }
  106. #if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
  107. // We avoid including malloc.h for portability reasons.
  108. // man mallinfo says the fields are "long", but the implementation uses int.
  109. // It doesn't matter much -- we just need to make sure that the libc's mallinfo
  110. // is not called.
  111. struct fake_mallinfo {
  112. int x[10];
  113. };
  114. INTERCEPTOR(struct fake_mallinfo, mallinfo, void) {
  115. struct fake_mallinfo res;
  116. REAL(memset)(&res, 0, sizeof(res));
  117. return res;
  118. }
  119. INTERCEPTOR(int, mallopt, int cmd, int value) {
  120. return 0;
  121. }
  122. #endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
  123. INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {
  124. GET_STACK_TRACE_MALLOC;
  125. return asan_posix_memalign(memptr, alignment, size, &stack);
  126. }
  127. INTERCEPTOR(void*, valloc, uptr size) {
  128. GET_STACK_TRACE_MALLOC;
  129. return asan_valloc(size, &stack);
  130. }
  131. #if SANITIZER_INTERCEPT_PVALLOC
  132. INTERCEPTOR(void*, pvalloc, uptr size) {
  133. GET_STACK_TRACE_MALLOC;
  134. return asan_pvalloc(size, &stack);
  135. }
  136. #endif // SANITIZER_INTERCEPT_PVALLOC
  137. INTERCEPTOR(void, malloc_stats, void) {
  138. __asan_print_accumulated_stats();
  139. }
  140. #if SANITIZER_ANDROID
  141. // Format of __libc_malloc_dispatch has changed in Android L.
  142. // While we are moving towards a solution that does not depend on bionic
  143. // internals, here is something to support both K* and L releases.
  144. struct MallocDebugK {
  145. void *(*malloc)(uptr bytes);
  146. void (*free)(void *mem);
  147. void *(*calloc)(uptr n_elements, uptr elem_size);
  148. void *(*realloc)(void *oldMem, uptr bytes);
  149. void *(*memalign)(uptr alignment, uptr bytes);
  150. uptr (*malloc_usable_size)(void *mem);
  151. };
  152. struct MallocDebugL {
  153. void *(*calloc)(uptr n_elements, uptr elem_size);
  154. void (*free)(void *mem);
  155. fake_mallinfo (*mallinfo)(void);
  156. void *(*malloc)(uptr bytes);
  157. uptr (*malloc_usable_size)(void *mem);
  158. void *(*memalign)(uptr alignment, uptr bytes);
  159. int (*posix_memalign)(void **memptr, uptr alignment, uptr size);
  160. void* (*pvalloc)(uptr size);
  161. void *(*realloc)(void *oldMem, uptr bytes);
  162. void* (*valloc)(uptr size);
  163. };
  164. ALIGNED(32) const MallocDebugK asan_malloc_dispatch_k = {
  165. WRAP(malloc), WRAP(free), WRAP(calloc),
  166. WRAP(realloc), WRAP(memalign), WRAP(malloc_usable_size)};
  167. ALIGNED(32) const MallocDebugL asan_malloc_dispatch_l = {
  168. WRAP(calloc), WRAP(free), WRAP(mallinfo),
  169. WRAP(malloc), WRAP(malloc_usable_size), WRAP(memalign),
  170. WRAP(posix_memalign), WRAP(pvalloc), WRAP(realloc),
  171. WRAP(valloc)};
  172. namespace __asan {
  173. void ReplaceSystemMalloc() {
  174. void **__libc_malloc_dispatch_p =
  175. (void **)AsanDlSymNext("__libc_malloc_dispatch");
  176. if (__libc_malloc_dispatch_p) {
  177. // Decide on K vs L dispatch format by the presence of
  178. // __libc_malloc_default_dispatch export in libc.
  179. void *default_dispatch_p = AsanDlSymNext("__libc_malloc_default_dispatch");
  180. if (default_dispatch_p)
  181. *__libc_malloc_dispatch_p = (void *)&asan_malloc_dispatch_k;
  182. else
  183. *__libc_malloc_dispatch_p = (void *)&asan_malloc_dispatch_l;
  184. }
  185. }
  186. } // namespace __asan
  187. #else // SANITIZER_ANDROID
  188. namespace __asan {
  189. void ReplaceSystemMalloc() {
  190. }
  191. } // namespace __asan
  192. #endif // SANITIZER_ANDROID
  193. #endif // SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX ||
  194. // SANITIZER_NETBSD || SANITIZER_SOLARIS