diff options
| author | babenko <[email protected]> | 2025-02-02 18:55:14 +0300 |
|---|---|---|
| committer | babenko <[email protected]> | 2025-02-02 19:09:58 +0300 |
| commit | e249111c11224174f38e5fb2160fcf9348243f3d (patch) | |
| tree | 5b7d865b3d2cc9786913f61bbd30a841aef9d88a | |
| parent | cb22a5d185b32388e41d8d2b75245b6340cf7817 (diff) | |
YT-24061: ROPSan: tagging sanitizer for master raw object pointers
Master is currently swarming with raw object pointers and this is not likely to change much in the nearest future.
Goal 1: For production/prestable builds: prevent master from writing inconsistent and broken snapshots from state containing dangling pointers.
Goal 2: For testing/debug builds: enable early detection of dangling pointer use.
Enter ROPSan: Raw Pointer Object Sanitizer!
`TRawObjectPtr<T>` is a drop-in replacement for `T*` that is 95%-compatible with raw pointer. For convenience, `TSomethingRawPtr` is auto-declared for each master type `TSomething`.
One need not replace `T*` with `TRawObjectPtr<T>` everywhere but is expected to do so for fields comprising master state (these are serialized in `Save/Load/Persist` methods). To incentivize this, we are no longer providing automatic serializers for raw pointers to master object types.
In release build, `TRawObjectPtr<T>` reduces to a trivial wrapper around `T*` and is not expected to cause any overhead.
In checked builds, `TRawObjectPtr` becomes tagged: its highest 16 bits are used to (statistically) detect use-after-free scenarios. Each `TObject` is also tagged with a random 16-bit value during construction. This tag is read from the object and is incorporated into `TRawObjectPtr` upon conversion for raw pointer. Tags are checked each time `TRawObjectPtr` is used. When an object is destructed, its tag is overwritten with `0xdead` sentinel value.
See `yt/yt/server/master/object_server/public.h` for a detailed list of control knobs.
commit_hash:b0a4cd39f0cbae7ca5c7486fd7fca4a32ad4cffe
| -rw-r--r-- | yt/yt/core/misc/serialize-inl.h | 20 | ||||
| -rw-r--r-- | yt/yt/core/misc/serialize.h | 9 |
2 files changed, 29 insertions, 0 deletions
diff --git a/yt/yt/core/misc/serialize-inl.h b/yt/yt/core/misc/serialize-inl.h index 38fea1742e1..342183b41e9 100644 --- a/yt/yt/core/misc/serialize-inl.h +++ b/yt/yt/core/misc/serialize-inl.h @@ -458,6 +458,26 @@ T Load(C& context, TArgs&&... args) return value; } +template <class TSerializer, class T, class C, class... TArgs> +void SaveWith(C& context, const T& value, TArgs&&... args) +{ + TSerializer::Save(context, value, std::forward<TArgs>(args)...); +} + +template <class TSerializer, class T, class C, class... TArgs> +void LoadWith(C& context, T& value, TArgs&&... args) +{ + TSerializer::Load(context, value, std::forward<TArgs>(args)...); +} + +template <class TSerializer, class T, class C, class... TArgs> +T LoadWith(C& context, TArgs&&... args) +{ + T value{}; + TSerializer::Load(context, value, std::forward<TArgs>(args)...); + return value; +} + template <class T, class C, class... TArgs> T LoadSuspended(C& context, TArgs&&... args) { diff --git a/yt/yt/core/misc/serialize.h b/yt/yt/core/misc/serialize.h index d51a5012cf9..33671b73c96 100644 --- a/yt/yt/core/misc/serialize.h +++ b/yt/yt/core/misc/serialize.h @@ -325,6 +325,15 @@ void Load(C& context, T& value, TArgs&&... args); template <class T, class C, class... TArgs> T Load(C& context, TArgs&&... args); +template <class TSerializer, class T, class C, class... TArgs> +void LoadWith(C& context, T& value, TArgs&&... args); + +template <class TSerializer, class T, class C, class... TArgs> +void SaveWith(C& context, const T& value, TArgs&&... args); + +template <class TSerializer, class T, class C, class... TArgs> +T LoadWith(C& context, TArgs&&... args); + //////////////////////////////////////////////////////////////////////////////// } // namespace NYT |
