Line data Source code
1 : /*
2 : * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #ifndef WEBRTC_BASE_SANITIZER_H_
12 : #define WEBRTC_BASE_SANITIZER_H_
13 :
14 : #if defined(__has_feature)
15 : #if __has_feature(address_sanitizer)
16 : #define RTC_HAS_ASAN 1
17 : #endif
18 : #if __has_feature(memory_sanitizer)
19 : #define RTC_HAS_MSAN 1
20 : #endif
21 : #endif
22 : #ifndef RTC_HAS_ASAN
23 : #define RTC_HAS_ASAN 0
24 : #endif
25 : #ifndef RTC_HAS_MSAN
26 : #define RTC_HAS_MSAN 0
27 : #endif
28 :
29 : #if RTC_HAS_ASAN
30 : #include <sanitizer/asan_interface.h>
31 : #endif
32 : #if RTC_HAS_MSAN
33 : #include <sanitizer/msan_interface.h>
34 : #endif
35 :
36 : #ifdef __has_attribute
37 : #if __has_attribute(no_sanitize)
38 : #define RTC_NO_SANITIZE(what) __attribute__((no_sanitize(what)))
39 : #endif
40 : #endif
41 : #ifndef RTC_NO_SANITIZE
42 : #define RTC_NO_SANITIZE(what)
43 : #endif
44 :
45 : // Ask ASan to mark the memory range [ptr, ptr + element_size * num_elements)
46 : // as being unaddressable, so that reads and writes are not allowed. ASan may
47 : // narrow the range to the nearest alignment boundaries.
48 0 : static inline void rtc_AsanPoison(const volatile void* ptr,
49 : size_t element_size,
50 : size_t num_elements) {
51 : #if RTC_HAS_ASAN
52 : ASAN_POISON_MEMORY_REGION(ptr, element_size * num_elements);
53 : #endif
54 0 : }
55 :
56 : // Ask ASan to mark the memory range [ptr, ptr + element_size * num_elements)
57 : // as being addressable, so that reads and writes are allowed. ASan may widen
58 : // the range to the nearest alignment boundaries.
59 0 : static inline void rtc_AsanUnpoison(const volatile void* ptr,
60 : size_t element_size,
61 : size_t num_elements) {
62 : #if RTC_HAS_ASAN
63 : ASAN_UNPOISON_MEMORY_REGION(ptr, element_size * num_elements);
64 : #endif
65 0 : }
66 :
67 : // Ask MSan to mark the memory range [ptr, ptr + element_size * num_elements)
68 : // as being uninitialized.
69 0 : static inline void rtc_MsanMarkUninitialized(const volatile void* ptr,
70 : size_t element_size,
71 : size_t num_elements) {
72 : #if RTC_HAS_MSAN
73 : __msan_poison(ptr, element_size * num_elements);
74 : #endif
75 0 : }
76 :
77 : // Force an MSan check (if any bits in the memory range [ptr, ptr +
78 : // element_size * num_elements) are uninitialized the call will crash with an
79 : // MSan report).
80 0 : static inline void rtc_MsanCheckInitialized(const volatile void* ptr,
81 : size_t element_size,
82 : size_t num_elements) {
83 : #if RTC_HAS_MSAN
84 : __msan_check_mem_is_initialized(ptr, element_size * num_elements);
85 : #endif
86 0 : }
87 :
88 : #ifdef __cplusplus
89 :
90 : namespace rtc {
91 :
92 : template <typename T>
93 0 : inline void AsanPoison(const T& mem) {
94 0 : rtc_AsanPoison(mem.data(), sizeof(mem.data()[0]), mem.size());
95 0 : }
96 :
97 : template <typename T>
98 0 : inline void AsanUnpoison(const T& mem) {
99 0 : rtc_AsanUnpoison(mem.data(), sizeof(mem.data()[0]), mem.size());
100 0 : }
101 :
102 : template <typename T>
103 0 : inline void MsanMarkUninitialized(const T& mem) {
104 0 : rtc_MsanMarkUninitialized(mem.data(), sizeof(mem.data()[0]), mem.size());
105 0 : }
106 :
107 : template <typename T>
108 0 : inline void MsanCheckInitialized(const T& mem) {
109 0 : rtc_MsanCheckInitialized(mem.data(), sizeof(mem.data()[0]), mem.size());
110 0 : }
111 :
112 : } // namespace rtc
113 :
114 : #endif // __cplusplus
115 :
116 : #endif // WEBRTC_BASE_SANITIZER_H_
|