aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbabenko <babenko@yandex-team.com>2025-03-04 08:59:30 +0300
committerbabenko <babenko@yandex-team.com>2025-03-04 09:57:20 +0300
commit1045f78299d073b1034b70098d42c7da2a378aad (patch)
tree56464686c47cb4291ecee508c6ef48878e9f6c42
parent875cc9c0de3e65ec0e587e991c825c3f2c173f21 (diff)
downloadydb-1045f78299d073b1034b70098d42c7da2a378aad.tar.gz
Add poisoning helpers
commit_hash:af266bdf36204a4190b491ea5c45455457030edf
-rw-r--r--library/cpp/yt/memory/non_null_ptr-inl.h2
-rw-r--r--library/cpp/yt/memory/poison-inl.h60
-rw-r--r--library/cpp/yt/memory/poison.cpp64
-rw-r--r--library/cpp/yt/memory/poison.h25
-rw-r--r--library/cpp/yt/memory/range.h11
-rw-r--r--library/cpp/yt/memory/ya.make1
6 files changed, 162 insertions, 1 deletions
diff --git a/library/cpp/yt/memory/non_null_ptr-inl.h b/library/cpp/yt/memory/non_null_ptr-inl.h
index a14b1e9302..d4d00c5549 100644
--- a/library/cpp/yt/memory/non_null_ptr-inl.h
+++ b/library/cpp/yt/memory/non_null_ptr-inl.h
@@ -1,6 +1,6 @@
#pragma once
#ifndef NON_NULL_PTR_H_
-#error "Direct inclusion of this file is not allowed, include helpers.h"
+#error "Direct inclusion of this file is not allowed, include non_null_ptr.h"
// For the sake of sane code completion.
#include "non_null_ptr.h"
#endif
diff --git a/library/cpp/yt/memory/poison-inl.h b/library/cpp/yt/memory/poison-inl.h
new file mode 100644
index 0000000000..c7563565a8
--- /dev/null
+++ b/library/cpp/yt/memory/poison-inl.h
@@ -0,0 +1,60 @@
+#pragma once
+#ifndef POISON_INL_H_
+#error "Direct inclusion of this file is not allowed, include poison.h"
+// For the sake of sane code completion.
+#include "poison.h"
+#endif
+
+#include <util/system/compiler.h>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+#if defined(_asan_enabled_)
+
+extern "C" {
+void __asan_poison_memory_region(void const volatile *addr, size_t size);
+void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
+} // extern "C"
+
+Y_FORCE_INLINE void PoisonMemory(TMutableRef ref)
+{
+ __asan_poison_memory_region(ref.data(), ref.size());
+}
+
+Y_FORCE_INLINE void UnpoisonMemory(TMutableRef ref)
+{
+ __asan_unpoison_memory_region(ref.data(), ref.size());
+}
+
+#elif defined(_msan_enabled_)
+
+extern "C" {
+void __msan_unpoison(const volatile void* a, size_t size);
+void __msan_poison(const volatile void* a, size_t size);
+} // extern "C"
+
+Y_FORCE_INLINE void PoisonMemory(TMutableRef ref)
+{
+ __msan_poison(ref.data(), ref.size());
+}
+
+Y_FORCE_INLINE void UnpoisonMemory(TMutableRef ref)
+{
+ __msan_unpoison(ref.data(), ref.size());
+}
+
+#elif defined(NDEBUG)
+
+Y_FORCE_INLINE void PoisonMemory(TMutableRef /*ref*/)
+{ }
+
+Y_FORCE_INLINE void UnpoisonMemory(TMutableRef /*ref*/)
+{ }
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/memory/poison.cpp b/library/cpp/yt/memory/poison.cpp
new file mode 100644
index 0000000000..bc4bcad4e0
--- /dev/null
+++ b/library/cpp/yt/memory/poison.cpp
@@ -0,0 +1,64 @@
+#include "poison.h"
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+template <char Byte0, char Byte1, char Byte2, char Byte3, char Byte4, char Byte5, char Byte6, char Byte7>
+void ClobberMemory(char* __restrict__ ptr, size_t size)
+{
+ while (size >= 8) {
+ *ptr++ = Byte0;
+ *ptr++ = Byte1;
+ *ptr++ = Byte2;
+ *ptr++ = Byte3;
+ *ptr++ = Byte4;
+ *ptr++ = Byte5;
+ *ptr++ = Byte6;
+ *ptr++ = Byte7;
+ size -= 8;
+ }
+
+ switch (size) {
+ case 7:
+ *ptr++ = Byte0;
+ [[fallthrough]];
+ case 6:
+ *ptr++ = Byte1;
+ [[fallthrough]];
+ case 5:
+ *ptr++ = Byte2;
+ [[fallthrough]];
+ case 4:
+ *ptr++ = Byte3;
+ [[fallthrough]];
+ case 3:
+ *ptr++ = Byte4;
+ [[fallthrough]];
+ case 2:
+ *ptr++ = Byte5;
+ [[fallthrough]];
+ case 1:
+ *ptr++ = Byte6;
+ }
+}
+
+} // namespace
+
+#if !defined(NDEBUG) && !defined(_asan_enabled_) && !defined(_msan_enabled_)
+void PoisonMemory(TMutableRef ref)
+{
+ ClobberMemory<'d', 'e', 'a', 'd', 'b', 'e', 'e', 'f'>(ref.data(), ref.size());
+}
+
+void UnpoisonMemory(TMutableRef ref)
+{
+ ClobberMemory<'c', 'a', 'f', 'e', 'b', 'a', 'b', 'e'>(ref.data(), ref.size());
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
diff --git a/library/cpp/yt/memory/poison.h b/library/cpp/yt/memory/poison.h
new file mode 100644
index 0000000000..9519f3da10
--- /dev/null
+++ b/library/cpp/yt/memory/poison.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "ref.h"
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+//! In release builds, does nothing.
+//! In checked builds, clobbers memory with garbage pattern.
+//! In sanitized builds, invokes sanitizer poisoning.
+void PoisonMemory(TMutableRef ref);
+
+//! In release builds, does nothing.
+//! In checked builds, clobbers memory with (another) garbage pattern.
+//! In sanitized builds, invokes sanitizer unpoisoning.
+void UnpoisonMemory(TMutableRef ref);
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT
+
+#define POISON_INL_H_
+#include "poison-inl.h"
+#undef POISON_INL_H_
diff --git a/library/cpp/yt/memory/range.h b/library/cpp/yt/memory/range.h
index 420ee9b429..84ea2e7758 100644
--- a/library/cpp/yt/memory/range.h
+++ b/library/cpp/yt/memory/range.h
@@ -354,12 +354,23 @@ public:
: TRange<T>(elements)
{ }
+ using TRange<T>::Data;
using TRange<T>::Begin;
using TRange<T>::End;
using TRange<T>::Front;
using TRange<T>::Back;
using TRange<T>::operator[];
+ T* Data() const
+ {
+ return const_cast<T*>(this->Data_);
+ }
+
+ T* data() const
+ {
+ return Data();
+ }
+
iterator Begin() const
{
return const_cast<T*>(this->Data_);
diff --git a/library/cpp/yt/memory/ya.make b/library/cpp/yt/memory/ya.make
index 5397dccf32..d0c377cf3d 100644
--- a/library/cpp/yt/memory/ya.make
+++ b/library/cpp/yt/memory/ya.make
@@ -16,6 +16,7 @@ SRCS(
chunked_output_stream.cpp
memory_tag.cpp
new.cpp
+ poison.cpp
ref.cpp
ref_tracked.cpp
safe_memory_reader.cpp