hwasan_new_delete.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //===-- hwasan_new_delete.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 HWAddressSanitizer.
  10. //
  11. // Interceptors for operators new and delete.
  12. //===----------------------------------------------------------------------===//
  13. #include "hwasan.h"
  14. #include "interception/interception.h"
  15. #include "sanitizer_common/sanitizer_allocator.h"
  16. #include "sanitizer_common/sanitizer_allocator_report.h"
  17. #include <stddef.h>
  18. #include <stdlib.h>
  19. #if HWASAN_REPLACE_OPERATORS_NEW_AND_DELETE
  20. // TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
  21. # define OPERATOR_NEW_BODY(nothrow) \
  22. GET_MALLOC_STACK_TRACE; \
  23. void *res = hwasan_malloc(size, &stack); \
  24. if (!nothrow && UNLIKELY(!res)) \
  25. ReportOutOfMemory(size, &stack); \
  26. return res
  27. # define OPERATOR_NEW_ALIGN_BODY(nothrow) \
  28. GET_MALLOC_STACK_TRACE; \
  29. void *res = hwasan_memalign(static_cast<uptr>(align), size, &stack); \
  30. if (!nothrow && UNLIKELY(!res)) \
  31. ReportOutOfMemory(size, &stack); \
  32. return res
  33. # define OPERATOR_DELETE_BODY \
  34. GET_MALLOC_STACK_TRACE; \
  35. if (ptr) \
  36. hwasan_free(ptr, &stack)
  37. #elif defined(__ANDROID__)
  38. // We don't actually want to intercept operator new and delete on Android, but
  39. // since we previously released a runtime that intercepted these functions,
  40. // removing the interceptors would break ABI. Therefore we simply forward to
  41. // malloc and free.
  42. # define OPERATOR_NEW_BODY(nothrow) return malloc(size)
  43. # define OPERATOR_DELETE_BODY free(ptr)
  44. #endif
  45. #ifdef OPERATOR_NEW_BODY
  46. using namespace __hwasan;
  47. // Fake std::nothrow_t to avoid including <new>.
  48. namespace std {
  49. struct nothrow_t {};
  50. } // namespace std
  51. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new(size_t size) {
  52. OPERATOR_NEW_BODY(false /*nothrow*/);
  53. }
  54. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new[](
  55. size_t size) {
  56. OPERATOR_NEW_BODY(false /*nothrow*/);
  57. }
  58. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new(
  59. size_t size, std::nothrow_t const &) {
  60. OPERATOR_NEW_BODY(true /*nothrow*/);
  61. }
  62. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new[](
  63. size_t size, std::nothrow_t const &) {
  64. OPERATOR_NEW_BODY(true /*nothrow*/);
  65. }
  66. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(
  67. void *ptr) NOEXCEPT {
  68. OPERATOR_DELETE_BODY;
  69. }
  70. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
  71. void *ptr) NOEXCEPT {
  72. OPERATOR_DELETE_BODY;
  73. }
  74. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(
  75. void *ptr, std::nothrow_t const &) {
  76. OPERATOR_DELETE_BODY;
  77. }
  78. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
  79. void *ptr, std::nothrow_t const &) {
  80. OPERATOR_DELETE_BODY;
  81. }
  82. #endif // OPERATOR_NEW_BODY
  83. #ifdef OPERATOR_NEW_ALIGN_BODY
  84. namespace std {
  85. enum class align_val_t : size_t {};
  86. } // namespace std
  87. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new(
  88. size_t size, std::align_val_t align) {
  89. OPERATOR_NEW_ALIGN_BODY(false /*nothrow*/);
  90. }
  91. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new[](
  92. size_t size, std::align_val_t align) {
  93. OPERATOR_NEW_ALIGN_BODY(false /*nothrow*/);
  94. }
  95. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new(
  96. size_t size, std::align_val_t align, std::nothrow_t const &) {
  97. OPERATOR_NEW_ALIGN_BODY(true /*nothrow*/);
  98. }
  99. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new[](
  100. size_t size, std::align_val_t align, std::nothrow_t const &) {
  101. OPERATOR_NEW_ALIGN_BODY(true /*nothrow*/);
  102. }
  103. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(
  104. void *ptr, std::align_val_t align) NOEXCEPT {
  105. OPERATOR_DELETE_BODY;
  106. }
  107. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
  108. void *ptr, std::align_val_t) NOEXCEPT {
  109. OPERATOR_DELETE_BODY;
  110. }
  111. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(
  112. void *ptr, std::align_val_t, std::nothrow_t const &) NOEXCEPT {
  113. OPERATOR_DELETE_BODY;
  114. }
  115. INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
  116. void *ptr, std::align_val_t, std::nothrow_t const &) NOEXCEPT {
  117. OPERATOR_DELETE_BODY;
  118. }
  119. #endif // OPERATOR_NEW_ALIGN_BODY