rtc::MsanUninitialized to mark a trivially copiable object as uninitialized
Setting a default value for a class members prevents memory sanitizer
to behave correctly and may confuse the reader.
Instead, one should use rtc::MsanUninitialized, which creates an object of
a given type and marks its memory as uninitialized.
This prevents issues in production (due to uninitialized memory) and
allows MemorySantizier to catch invalid access patterns.
Bug: webrtc:8762
Change-Id: I74c79caa9c19ea85708e89e24bc5516c4d9d12a1
Reviewed-on: https://webrtc-review.googlesource.com/52342
Commit-Queue: Alessio Bazzica <alessiob@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22773}
diff --git a/rtc_base/sanitizer.h b/rtc_base/sanitizer.h
index 1b94e1e..23a748f 100644
--- a/rtc_base/sanitizer.h
+++ b/rtc_base/sanitizer.h
@@ -11,7 +11,11 @@
#ifndef RTC_BASE_SANITIZER_H_
#define RTC_BASE_SANITIZER_H_
-#include <stddef.h> // for size_t
+#include <stddef.h> // For size_t.
+
+#ifdef __cplusplus
+#include <type_traits>
+#endif
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
@@ -90,6 +94,17 @@
#ifdef __cplusplus
namespace rtc {
+namespace sanitizer_impl {
+
+template <typename T>
+constexpr bool IsTriviallyCopyable() {
+ return static_cast<bool>(std::is_trivially_copy_constructible<T>::value &&
+ (std::is_trivially_copy_assignable<T>::value ||
+ !std::is_copy_assignable<T>::value) &&
+ std::is_trivially_destructible<T>::value);
+}
+
+} // namespace sanitizer_impl
template <typename T>
inline void AsanPoison(const T& mem) {
@@ -107,6 +122,15 @@
}
template <typename T>
+inline T MsanUninitialized(T t) {
+ // TODO(bugs.webrtc.org/8762): Switch to std::is_trivially_copyable when it
+ // becomes available in downstream projects.
+ static_assert(sanitizer_impl::IsTriviallyCopyable<T>(), "");
+ rtc_MsanMarkUninitialized(&t, sizeof(T), 1);
+ return t;
+}
+
+template <typename T>
inline void MsanCheckInitialized(const T& mem) {
rtc_MsanCheckInitialized(mem.data(), sizeof(mem.data()[0]), mem.size());
}