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
14#include "hwasan.h"
15#include "interception/interception.h"
16#include "sanitizer_common/sanitizer_allocator.h"
17#include "sanitizer_common/sanitizer_allocator_report.h"
18
19#if HWASAN_REPLACE_OPERATORS_NEW_AND_DELETE
20
21#include <stddef.h>
22
23using namespace __hwasan;
24
25// Fake std::nothrow_t to avoid including <new>.
26namespace std {
27  struct nothrow_t {};
28}  // namespace std
29
30
31// TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
32#define OPERATOR_NEW_BODY(nothrow) \
33  GET_MALLOC_STACK_TRACE; \
34  void *res = hwasan_malloc(size, &stack);\
35  if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
36  return res
37
38INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
39void *operator new(size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
40INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
41void *operator new[](size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); }
42INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
43void *operator new(size_t size, std::nothrow_t const&) {
44  OPERATOR_NEW_BODY(true /*nothrow*/);
45}
46INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
47void *operator new[](size_t size, std::nothrow_t const&) {
48  OPERATOR_NEW_BODY(true /*nothrow*/);
49}
50
51#define OPERATOR_DELETE_BODY \
52  GET_MALLOC_STACK_TRACE; \
53  if (ptr) hwasan_free(ptr, &stack)
54
55INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
56void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
57INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
58void operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
59INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
60void operator delete(void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY; }
61INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
62void operator delete[](void *ptr, std::nothrow_t const&) {
63  OPERATOR_DELETE_BODY;
64}
65
66#endif // HWASAN_REPLACE_OPERATORS_NEW_AND_DELETE
67