aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2014-06-24 15:27:37 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2014-06-26 15:15:17 +0200
commit8ae973c00cfb02161bb2c2a6c839e510cd409278 (patch)
tree26796124f38b81c31dcfd1908268a06bb246757c
parentbe873f64540d3c0b1227920eb466097ed738f452 (diff)
Allocate more space if necessary in RandSeedAddPerfMon
Currently we use a fixed buffer of 250000 bytes to request HKEY_PERFORMANCE_DATA. In many cases this is not enough, causing the entropy collection to be skipped. Use a loop that grows the buffer as specified in the RegQueryValueEx documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724911%28v=vs.85%29.aspx (as the size of the performance data can differ for every call, the normal solution of requesting the size then allocating that can't work)
-rw-r--r--src/util.cpp13
1 files changed, 11 insertions, 2 deletions
diff --git a/src/util.cpp b/src/util.cpp
index 7946089571..a96963689a 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -169,8 +169,17 @@ void RandAddSeedPerfmon()
// Don't need this on Linux, OpenSSL automatically uses /dev/urandom
// Seed with the entire set of perfmon data
std::vector <unsigned char> vData(250000,0);
- unsigned long nSize = vData.size();
- long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, begin_ptr(vData), &nSize);
+ long ret = 0;
+ unsigned long nSize = 0;
+ const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
+ while (true)
+ {
+ nSize = vData.size();
+ ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, begin_ptr(vData), &nSize);
+ if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
+ break;
+ vData.resize(std::max((vData.size()*3)/2, nMaxSize)); // Grow size of buffer exponentially
+ }
RegCloseKey(HKEY_PERFORMANCE_DATA);
if (ret == ERROR_SUCCESS)
{