blob: 49dc670fd1efc604c74e737f4af9240f727906f5 [file] [log] [blame]
Henrik Kjellander67765182017-06-28 20:58:07 +02001/*
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_RTC_BASE_SANITIZER_H_
12#define WEBRTC_RTC_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.
48static 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}
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.
59static 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}
66
67// Ask MSan to mark the memory range [ptr, ptr + element_size * num_elements)
68// as being uninitialized.
69static 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}
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).
80static 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}
87
88#ifdef __cplusplus
89
90namespace rtc {
91
92template <typename T>
93inline void AsanPoison(const T& mem) {
94 rtc_AsanPoison(mem.data(), sizeof(mem.data()[0]), mem.size());
95}
96
97template <typename T>
98inline void AsanUnpoison(const T& mem) {
99 rtc_AsanUnpoison(mem.data(), sizeof(mem.data()[0]), mem.size());
100}
101
102template <typename T>
103inline void MsanMarkUninitialized(const T& mem) {
104 rtc_MsanMarkUninitialized(mem.data(), sizeof(mem.data()[0]), mem.size());
105}
106
107template <typename T>
108inline void MsanCheckInitialized(const T& mem) {
109 rtc_MsanCheckInitialized(mem.data(), sizeof(mem.data()[0]), mem.size());
110}
111
112} // namespace rtc
113
114#endif // __cplusplus
115
116#endif // WEBRTC_RTC_BASE_SANITIZER_H_