Template for automatically overwriting memory upon destruction

A common pattern is to use patterns to force the compiler to initialize primitive / POD type values ​​( https://stackoverflow.com/a/products/924509/... or http://www.codeproject.com/Articles/825/Using-templates-for-initialization )

Is there a similar model that can be used to erase a value after it leaves the scope for security reasons, to make sure that the value does not remain on the stack after the variable is destroyed? I am afraid that a naive similar implementation might not work, because the compiler may ignore any assignments to a value that is beyond the scope, as the value may be trivially proven that it is no longer used. Is there some kind of coherent and reasonably portable solution, for example. using volatile?

+6
source share
2 answers

You can use some of the features of C ++ 11 to make it more portable, but this may be sufficient as a starting point:

Class

template<typename T> class t_secure_destruct { static const size_t Size = sizeof(T); static const size_t Align = alignof(T); public: t_secure_destruct() : d_memory() { new(this->d_memory)T; } ~t_secure_destruct() { reinterpret_cast<T*>(this->d_memory)->~T(); this->scribble(); } // @todo implement or delete op-assign and remaining constructors public: T& get() { return *reinterpret_cast<T*>(this->d_memory); } const T& get() const { return *reinterpret_cast<const T*>(this->d_memory); } private: void scribble() { for (size_t idx(0); idx < Size; ++idx) { this->d_memory[idx] = random(); } } private: __attribute__((aligned(Align))) char d_memory[Size]; }; 

Demo

 #include <iostream> class t_test { public: t_test() : a(-1) { std::cout << "construct\n"; } ~t_test() { std::cout << "destruct\n"; } public: void print() const { std::cout << "a = " << a << "\n"; } public: int a; }; int main(int argc, const char* argv[]) { t_secure_destruct<t_test>test; test.get().print(); test.get().a = 100; test.get().print(); return 0; } 

Of course, you could also return this distribution with a heap distribution if you want. If you need to outsmart the optimizer, you may need to take it out of reach.

+3
source

The Windows API has a feature called SecureZeroMemory. You can look at its implementation.

However, generally speaking, the compiler is forced to observe volatile entries. If you made a variable volatile, it should not delete records.

+4
source

Source: https://habr.com/ru/post/924505/


All Articles