From fcb0a1bb9cea0e627152e544b0701c039cc3f60e Mon Sep 17 00:00:00 2001 From: daniel Date: Tue, 27 May 2014 11:44:55 +0800 Subject: [PATCH 1/3] change "char pch[200000]" to "new char[200000]" --- src/util.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 30590912ff..1480b2ebf8 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -168,15 +168,14 @@ void RandAddSeedPerfmon() #ifdef WIN32 // Don't need this on Linux, OpenSSL automatically uses /dev/urandom // Seed with the entire set of perfmon data - unsigned char pdata[250000]; - memset(pdata, 0, sizeof(pdata)); - unsigned long nSize = sizeof(pdata); - long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); + std::vector vData(250000,0); + unsigned long nSize = vData.size(); + long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, begin_ptr(vData), &nSize); RegCloseKey(HKEY_PERFORMANCE_DATA); if (ret == ERROR_SUCCESS) { - RAND_add(pdata, nSize, nSize/100.0); - OPENSSL_cleanse(pdata, nSize); + RAND_add(begin_ptr(vData), nSize, nSize/100.0); + OPENSSL_cleanse(begin_ptr(vData), nSize); LogPrint("rand", "RandAddSeed() %lu bytes\n", nSize); } #endif @@ -1141,15 +1140,15 @@ void ShrinkDebugFile() if (file && boost::filesystem::file_size(pathLog) > 10 * 1000000) { // Restart the file with some of the end - char pch[200000]; - fseek(file, -sizeof(pch), SEEK_END); - int nBytes = fread(pch, 1, sizeof(pch), file); + std::vector vch(200000,0); + fseek(file, -vch.size(), SEEK_END); + int nBytes = fread(begin_ptr(vch), 1, vch.size(), file); fclose(file); file = fopen(pathLog.string().c_str(), "w"); if (file) { - fwrite(pch, 1, nBytes, file); + fwrite(begin_ptr(vch), 1, nBytes, file); fclose(file); } } From be873f64540d3c0b1227920eb466097ed738f452 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 23 Jun 2014 14:35:35 +0200 Subject: [PATCH 2/3] Issue warning if collecting RandSeed data failed --- src/util.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/util.cpp b/src/util.cpp index 1480b2ebf8..7946089571 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -176,7 +176,14 @@ void RandAddSeedPerfmon() { RAND_add(begin_ptr(vData), nSize, nSize/100.0); OPENSSL_cleanse(begin_ptr(vData), nSize); - LogPrint("rand", "RandAddSeed() %lu bytes\n", nSize); + LogPrint("rand", "%s: %lu bytes\n", __func__, nSize); + } else { + static bool warned = false; // Warn only once + if (!warned) + { + LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret); + warned = true; + } } #endif } From 8ae973c00cfb02161bb2c2a6c839e510cd409278 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 24 Jun 2014 15:27:37 +0200 Subject: [PATCH 3/3] 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) --- src/util.cpp | 13 +++++++++++-- 1 file 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 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) {