diff options
author | babenko <babenko@yandex-team.com> | 2025-03-04 08:59:30 +0300 |
---|---|---|
committer | babenko <babenko@yandex-team.com> | 2025-03-04 09:57:20 +0300 |
commit | 1045f78299d073b1034b70098d42c7da2a378aad (patch) | |
tree | 56464686c47cb4291ecee508c6ef48878e9f6c42 | |
parent | 875cc9c0de3e65ec0e587e991c825c3f2c173f21 (diff) | |
download | ydb-1045f78299d073b1034b70098d42c7da2a378aad.tar.gz |
Add poisoning helpers
commit_hash:af266bdf36204a4190b491ea5c45455457030edf
-rw-r--r-- | library/cpp/yt/memory/non_null_ptr-inl.h | 2 | ||||
-rw-r--r-- | library/cpp/yt/memory/poison-inl.h | 60 | ||||
-rw-r--r-- | library/cpp/yt/memory/poison.cpp | 64 | ||||
-rw-r--r-- | library/cpp/yt/memory/poison.h | 25 | ||||
-rw-r--r-- | library/cpp/yt/memory/range.h | 11 | ||||
-rw-r--r-- | library/cpp/yt/memory/ya.make | 1 |
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 |