diff options
author | alexeylaptev <alexeylaptev@yandex-team.ru> | 2022-02-10 16:50:06 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:50:06 +0300 |
commit | 3106abc0443cda789ce4968aeee63d3a8fcc7d85 (patch) | |
tree | ec44b9884cc11c2a7b4f4dc7fd36a1ae1ba2d3db /library/cpp/coroutine/engine/stack/stack_guards.h | |
parent | a76f5e1efe665e1bb125f05ae275b2a6226517d9 (diff) | |
download | ydb-3106abc0443cda789ce4968aeee63d3a8fcc7d85.tar.gz |
Restoring authorship annotation for <alexeylaptev@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/coroutine/engine/stack/stack_guards.h')
-rw-r--r-- | library/cpp/coroutine/engine/stack/stack_guards.h | 244 |
1 files changed, 122 insertions, 122 deletions
diff --git a/library/cpp/coroutine/engine/stack/stack_guards.h b/library/cpp/coroutine/engine/stack/stack_guards.h index 3a7ef26481..c354339ed2 100644 --- a/library/cpp/coroutine/engine/stack/stack_guards.h +++ b/library/cpp/coroutine/engine/stack/stack_guards.h @@ -1,123 +1,123 @@ -#pragma once - -#include "stack_common.h" - -#include <util/generic/array_ref.h> -#include <util/generic/strbuf.h> -#include <util/system/protect.h> - - -namespace NCoro::NStack { - - /*! Guard detect stack overflow/override, by setting memory before and after stack with predefined values/properties. - * Actually, it sets memory only after the end of stack workspace memory - previous guard section should be set - * already (for previous stack in case of pool allocator) and can be checked on demand. - * Stack pointer should be page-aligned. - */ - - - //! Checks integrity by writing a predefined sequence and comparing it with original - class TCanaryGuard final { - public: - //! Size of guard section in bytes - static constexpr uint64_t GetSize() { return Canary.size(); } - //! Size of page-aligned guard section in bytes - static constexpr uint64_t GetPageAlignedSize() { return AlignedSize_; } - - //! Get stack memory between guard sections - static TArrayRef<char> GetWorkspace(void* stack, uint64_t size) noexcept { - Y_ASSERT( !((uint64_t)stack & PageSizeMask) ); - Y_ASSERT( !(size & PageSizeMask) ); - Y_ASSERT(size > Canary.size()); - - return {(char*) stack, size - Canary.size()}; - } - - /*! Set guard section before the end of stack memory (at stack + size - guard size position) - * checkPrevious: check guard before stack memory for integrity - */ - static void Protect(void* stack, uint64_t size, bool checkPrevious) noexcept { - Y_ASSERT( !((uint64_t)stack & PageSizeMask) ); // stack pointer should be page aligned - Y_ASSERT( !(size & PageSizeMask) ); // stack size should be page aligned - Y_ASSERT(size >= Canary.size()); // stack should have enough space to place guard - - if (checkPrevious) { - Y_VERIFY(CheckOverflow(stack), "Previous stack was corrupted"); - } - auto guardPos = (char*) stack + size - Canary.size(); - memcpy(guardPos, Canary.data(), Canary.size()); - } - - //! This guard doesn't change memory flags - static constexpr void RemoveProtection(void*, uint64_t) {} - //! Should remove protection before returning memory to system - static constexpr bool ShouldRemoveProtectionBeforeFree() { return false; } - - static bool CheckOverflow(void* stack) noexcept { - Y_ASSERT(stack); - - char* guardPos = (char*) ((uint64_t)stack - Canary.size()); - return TStringBuf(guardPos, Canary.size()) == Canary; - } - - static bool CheckOverride(void* stack, uint64_t size) noexcept { - Y_ASSERT(stack); - Y_ASSERT(size > Canary.size()); - - char* guardPos = (char*) ((uint64_t)stack + size - Canary.size()); - return TStringBuf(guardPos, Canary.size()) == Canary; - } - - private: +#pragma once + +#include "stack_common.h" + +#include <util/generic/array_ref.h> +#include <util/generic/strbuf.h> +#include <util/system/protect.h> + + +namespace NCoro::NStack { + + /*! Guard detect stack overflow/override, by setting memory before and after stack with predefined values/properties. + * Actually, it sets memory only after the end of stack workspace memory - previous guard section should be set + * already (for previous stack in case of pool allocator) and can be checked on demand. + * Stack pointer should be page-aligned. + */ + + + //! Checks integrity by writing a predefined sequence and comparing it with original + class TCanaryGuard final { + public: + //! Size of guard section in bytes + static constexpr uint64_t GetSize() { return Canary.size(); } + //! Size of page-aligned guard section in bytes + static constexpr uint64_t GetPageAlignedSize() { return AlignedSize_; } + + //! Get stack memory between guard sections + static TArrayRef<char> GetWorkspace(void* stack, uint64_t size) noexcept { + Y_ASSERT( !((uint64_t)stack & PageSizeMask) ); + Y_ASSERT( !(size & PageSizeMask) ); + Y_ASSERT(size > Canary.size()); + + return {(char*) stack, size - Canary.size()}; + } + + /*! Set guard section before the end of stack memory (at stack + size - guard size position) + * checkPrevious: check guard before stack memory for integrity + */ + static void Protect(void* stack, uint64_t size, bool checkPrevious) noexcept { + Y_ASSERT( !((uint64_t)stack & PageSizeMask) ); // stack pointer should be page aligned + Y_ASSERT( !(size & PageSizeMask) ); // stack size should be page aligned + Y_ASSERT(size >= Canary.size()); // stack should have enough space to place guard + + if (checkPrevious) { + Y_VERIFY(CheckOverflow(stack), "Previous stack was corrupted"); + } + auto guardPos = (char*) stack + size - Canary.size(); + memcpy(guardPos, Canary.data(), Canary.size()); + } + + //! This guard doesn't change memory flags + static constexpr void RemoveProtection(void*, uint64_t) {} + //! Should remove protection before returning memory to system + static constexpr bool ShouldRemoveProtectionBeforeFree() { return false; } + + static bool CheckOverflow(void* stack) noexcept { + Y_ASSERT(stack); + + char* guardPos = (char*) ((uint64_t)stack - Canary.size()); + return TStringBuf(guardPos, Canary.size()) == Canary; + } + + static bool CheckOverride(void* stack, uint64_t size) noexcept { + Y_ASSERT(stack); + Y_ASSERT(size > Canary.size()); + + char* guardPos = (char*) ((uint64_t)stack + size - Canary.size()); + return TStringBuf(guardPos, Canary.size()) == Canary; + } + + private: static constexpr TStringBuf Canary = "[ThisIsACanaryCoroutineStackGuardIfYouReadThisTheStackIsStillOK]"; - static_assert(Canary.size() == 64); - static constexpr uint64_t AlignedSize_ = (Canary.size() + PageSize - 1) & ~PageSizeMask; - }; - - - // ------------------------------------------------------------------------ - // - //! Ensures integrity by removing access rights for border pages - class TPageGuard final { - public: - //! Size of guard section in bytes - static constexpr uint64_t GetSize() { return PageSize; } - //! Size of page-aligned guard section in bytes - static constexpr uint64_t GetPageAlignedSize() { return PageSize; } - - static TArrayRef<char> GetWorkspace(void* stack, uint64_t size) noexcept { - Y_ASSERT( !((uint64_t)stack & PageSizeMask) ); - Y_ASSERT( !(size & PageSizeMask) ); - Y_ASSERT(size > PageSize); - - return {(char*)stack, size - PageSize}; - } - - static void Protect(void* stack, uint64_t size, bool /*checkPrevious*/) noexcept { - Y_ASSERT( !((uint64_t)stack & PageSizeMask) ); // stack pointer should be page aligned - Y_ASSERT( !(size & PageSizeMask) ); // stack size should be page aligned - Y_ASSERT(size >= PageSize); // stack should have enough space to place guard - - ProtectMemory((char*)stack + size - PageSize, PageSize, PM_NONE); - } - - //! Remove protection, to allow stack memory be freed - static void RemoveProtection(void* stack, uint64_t size) noexcept { - Y_ASSERT( !((uint64_t)stack & PageSizeMask) ); - Y_ASSERT( !(size & PageSizeMask) ); - Y_ASSERT(size >= PageSize); - - ProtectMemory((char*)stack + size - PageSize, PageSize, PM_WRITE | PM_READ); - } - //! Should remove protection before returning memory to system - static constexpr bool ShouldRemoveProtectionBeforeFree() { return true; } - - //! For page guard is not used - it crashes process at once in this case. - static constexpr bool CheckOverflow(void*) { return true; } - static constexpr bool CheckOverride(void*, uint64_t) { return true; } - }; - - - template<typename TGuard> - const TGuard& GetGuard() noexcept; -} + static_assert(Canary.size() == 64); + static constexpr uint64_t AlignedSize_ = (Canary.size() + PageSize - 1) & ~PageSizeMask; + }; + + + // ------------------------------------------------------------------------ + // + //! Ensures integrity by removing access rights for border pages + class TPageGuard final { + public: + //! Size of guard section in bytes + static constexpr uint64_t GetSize() { return PageSize; } + //! Size of page-aligned guard section in bytes + static constexpr uint64_t GetPageAlignedSize() { return PageSize; } + + static TArrayRef<char> GetWorkspace(void* stack, uint64_t size) noexcept { + Y_ASSERT( !((uint64_t)stack & PageSizeMask) ); + Y_ASSERT( !(size & PageSizeMask) ); + Y_ASSERT(size > PageSize); + + return {(char*)stack, size - PageSize}; + } + + static void Protect(void* stack, uint64_t size, bool /*checkPrevious*/) noexcept { + Y_ASSERT( !((uint64_t)stack & PageSizeMask) ); // stack pointer should be page aligned + Y_ASSERT( !(size & PageSizeMask) ); // stack size should be page aligned + Y_ASSERT(size >= PageSize); // stack should have enough space to place guard + + ProtectMemory((char*)stack + size - PageSize, PageSize, PM_NONE); + } + + //! Remove protection, to allow stack memory be freed + static void RemoveProtection(void* stack, uint64_t size) noexcept { + Y_ASSERT( !((uint64_t)stack & PageSizeMask) ); + Y_ASSERT( !(size & PageSizeMask) ); + Y_ASSERT(size >= PageSize); + + ProtectMemory((char*)stack + size - PageSize, PageSize, PM_WRITE | PM_READ); + } + //! Should remove protection before returning memory to system + static constexpr bool ShouldRemoveProtectionBeforeFree() { return true; } + + //! For page guard is not used - it crashes process at once in this case. + static constexpr bool CheckOverflow(void*) { return true; } + static constexpr bool CheckOverride(void*, uint64_t) { return true; } + }; + + + template<typename TGuard> + const TGuard& GetGuard() noexcept; +} |