Line data Source code
1 : // Copyright (c) 2014-2023 The Dash Core developers 2 : // Distributed under the MIT software license, see the accompanying 3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : 5 : #ifndef BITCOIN_SUPPORT_ALLOCATORS_POOLED_SECURE_H 6 : #define BITCOIN_SUPPORT_ALLOCATORS_POOLED_SECURE_H 7 : 8 : #include <support/lockedpool.h> 9 : #include <support/cleanse.h> 10 : 11 : #include <string> 12 : #include <vector> 13 : 14 : #include <boost/pool/pool_alloc.hpp> 15 : 16 : // 17 : // Allocator that allocates memory in chunks from a pool, which in turn allocates larger chunks from secure memory 18 : // Memory is cleaned when freed as well. This allocator is NOT thread safe 19 : // 20 : template <typename T> 21 : struct pooled_secure_allocator : public std::allocator<T> { 22 : using base = std::allocator<T>; 23 : using traits = std::allocator_traits<base>; 24 : using size_type = typename traits::size_type; 25 : using difference_type = typename traits::difference_type; 26 : using pointer = typename traits::pointer; 27 : using const_pointer = typename traits::const_pointer; 28 : using value_type = typename traits::value_type; 29 145 : pooled_secure_allocator(const size_type nrequested_size = 32, 30 : const size_type nnext_size = 32, 31 : const size_type nmax_size = 0) noexcept : 32 145 : pool(nrequested_size, nnext_size, nmax_size){} 33 145 : ~pooled_secure_allocator() noexcept {} 34 : 35 634 : T* allocate(std::size_t n, const void* hint = nullptr) 36 : { 37 634 : size_t chunks = (n * sizeof(T) + pool.get_requested_size() - 1) / pool.get_requested_size(); 38 634 : return static_cast<T*>(pool.ordered_malloc(chunks)); 39 : } 40 : 41 634 : void deallocate(T* p, std::size_t n) 42 : { 43 634 : if (!p) { 44 0 : return; 45 : } 46 : 47 634 : size_t chunks = (n * sizeof(T) + pool.get_requested_size() - 1) / pool.get_requested_size(); 48 634 : memory_cleanse(p, chunks * pool.get_requested_size()); 49 634 : pool.ordered_free(p, chunks); 50 634 : } 51 : 52 : public: 53 : struct internal_secure_allocator { 54 : typedef std::size_t size_type; 55 : typedef std::ptrdiff_t difference_type; 56 : 57 10 : static char* malloc(const size_type bytes) 58 : { 59 10 : return static_cast<char*>(LockedPoolManager::Instance().alloc(bytes)); 60 : } 61 : 62 10 : static void free(char* const block) 63 : { 64 10 : LockedPoolManager::Instance().free(block); 65 10 : } 66 : }; 67 : private: 68 : boost::pool<internal_secure_allocator> pool; 69 : }; 70 : 71 : #endif // BITCOIN_SUPPORT_ALLOCATORS_POOLED_SECURE_H