aboutsummaryrefslogtreecommitdiff
path: root/src/serialize.h
diff options
context:
space:
mode:
authorDylan Noblesmith <nobled@dreamwidth.org>2011-06-24 03:03:17 +0000
committerMatt Corallo <matt@bluematt.me>2011-07-08 15:46:47 +0200
commitc1aacf0be347b10a6ab9bbce841e8127412bce41 (patch)
tree8812660b7e1ced846fcacc565f22081ab3e9c70c /src/serialize.h
parentacd6501610817eee0bd1c8ea9c591f043affbaec (diff)
downloadbitcoin-c1aacf0be347b10a6ab9bbce841e8127412bce41.tar.xz
mlock() all private keys in memory
Inline comment and idea come from the encprivkeys branch by Matt Corallo <matt@bluematt.me>.
Diffstat (limited to 'src/serialize.h')
-rw-r--r--src/serialize.h27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/serialize.h b/src/serialize.h
index 31862a71a9..6952004e2e 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -28,6 +28,18 @@ typedef unsigned long long uint64;
#if defined(_MSC_VER) && _MSC_VER < 1300
#define for if (false) ; else for
#endif
+
+#ifdef __WXMSW__
+// This is used to attempt to keep keying material out of swap
+// Note that VirtualLock does not provide this as a guarantee on Windows,
+// but, in practice, memory that has been VirtualLock'd almost never gets written to
+// the pagefile except in rare circumstances where memory is extremely low.
+#define mlock(p, n) VirtualLock((p), (n));
+#define munlock(p, n) VirtualUnlock((p), (n));
+#else
+#include <sys/mman.h>
+#endif
+
class CScript;
class CDataStream;
class CAutoFile;
@@ -755,7 +767,8 @@ struct ser_streamplaceholder
//
-// Allocator that clears its contents before deletion
+// 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>
@@ -777,10 +790,22 @@ struct secure_allocator : public std::allocator<T>
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)
+ mlock(p, sizeof(T) * n);
+ return p;
+ }
+
void deallocate(T* p, std::size_t n)
{
if (p != NULL)
+ {
memset(p, 0, sizeof(T) * n);
+ munlock(p, sizeof(T) * n);
+ }
std::allocator<T>::deallocate(p, n);
}
};