diff options
author | Cory Fields <cory-nospam-@coryfields.com> | 2015-01-22 15:02:44 -0500 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2015-03-20 12:23:44 +0100 |
commit | d7d187e8a451ae946fa14cead7962edbe0046f12 (patch) | |
tree | caf6765dd0a9455891f14d2df42f164b56cfba13 /src/support/allocators | |
parent | c7abfa595dda5b74b0386532dc6a685ab1c7f009 (diff) |
allocators: split allocators and pagelocker
Pagelocker is only needed for secure (usually wallet) operations, so don't make
the zero-after-free allocator depend on it.
Diffstat (limited to 'src/support/allocators')
-rw-r--r-- | src/support/allocators/secure.h | 62 | ||||
-rw-r--r-- | src/support/allocators/zeroafterfree.h | 48 |
2 files changed, 110 insertions, 0 deletions
diff --git a/src/support/allocators/secure.h b/src/support/allocators/secure.h new file mode 100644 index 0000000000..7a74d87bb4 --- /dev/null +++ b/src/support/allocators/secure.h @@ -0,0 +1,62 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_ALLOCATORS_SECURE_H +#define BITCOIN_ALLOCATORS_SECURE_H + +#include "support/pagelocker.h" + +#include <string> + +// +// Allocator that locks its contents from being paged +// out of memory and clears its contents before deletion. +// +template <typename T> +struct secure_allocator : public std::allocator<T> { + // MSVC8 default copy constructor is broken + typedef std::allocator<T> base; + typedef typename base::size_type size_type; + typedef typename base::difference_type difference_type; + typedef typename base::pointer pointer; + typedef typename base::const_pointer const_pointer; + typedef typename base::reference reference; + typedef typename base::const_reference const_reference; + typedef typename base::value_type value_type; + secure_allocator() throw() {} + secure_allocator(const secure_allocator& a) throw() : base(a) {} + template <typename U> + secure_allocator(const secure_allocator<U>& a) throw() : base(a) + { + } + ~secure_allocator() throw() {} + template <typename _Other> + struct rebind { + typedef secure_allocator<_Other> other; + }; + + T* allocate(std::size_t n, const void* hint = 0) + { + T* p; + p = std::allocator<T>::allocate(n, hint); + if (p != NULL) + LockedPageManager::Instance().LockRange(p, sizeof(T) * n); + return p; + } + + void deallocate(T* p, std::size_t n) + { + if (p != NULL) { + memory_cleanse(p, sizeof(T) * n); + LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n); + } + std::allocator<T>::deallocate(p, n); + } +}; + +// This is exactly like std::string, but with a custom allocator. +typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString; + +#endif // BITCOIN_ALLOCATORS_SECURE_H diff --git a/src/support/allocators/zeroafterfree.h b/src/support/allocators/zeroafterfree.h new file mode 100644 index 0000000000..b01fcd088b --- /dev/null +++ b/src/support/allocators/zeroafterfree.h @@ -0,0 +1,48 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2013 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_ALLOCATORS_ZEROAFTERFREE_H +#define BITCOIN_ALLOCATORS_ZEROAFTERFREE_H + +#include "support/cleanse.h" + +#include <memory> +#include <vector> + +template <typename T> +struct zero_after_free_allocator : public std::allocator<T> { + // MSVC8 default copy constructor is broken + typedef std::allocator<T> base; + typedef typename base::size_type size_type; + typedef typename base::difference_type difference_type; + typedef typename base::pointer pointer; + typedef typename base::const_pointer const_pointer; + typedef typename base::reference reference; + typedef typename base::const_reference const_reference; + typedef typename base::value_type value_type; + zero_after_free_allocator() throw() {} + zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {} + template <typename U> + zero_after_free_allocator(const zero_after_free_allocator<U>& a) throw() : base(a) + { + } + ~zero_after_free_allocator() throw() {} + template <typename _Other> + struct rebind { + typedef zero_after_free_allocator<_Other> other; + }; + + void deallocate(T* p, std::size_t n) + { + if (p != NULL) + memory_cleanse(p, sizeof(T) * n); + std::allocator<T>::deallocate(p, n); + } +}; + +// Byte-vector that clears its contents before deletion. +typedef std::vector<char, zero_after_free_allocator<char> > CSerializeData; + +#endif // BITCOIN_ALLOCATORS_ZEROAFTERFREE_H |