aboutsummaryrefslogtreecommitdiff
path: root/crypto/rand/rand_win.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/rand/rand_win.c')
-rw-r--r--crypto/rand/rand_win.c69
1 files changed, 59 insertions, 10 deletions
diff --git a/crypto/rand/rand_win.c b/crypto/rand/rand_win.c
index 00dbe4232cc1..5198351cf34e 100644
--- a/crypto/rand/rand_win.c
+++ b/crypto/rand/rand_win.c
@@ -463,7 +463,7 @@ int RAND_poll(void)
PROCESSENTRY32 p;
THREADENTRY32 t;
MODULEENTRY32 m;
- DWORD stoptime = 0;
+ DWORD starttime = 0;
snap = (CREATETOOLHELP32SNAPSHOT)
GetProcAddress(kernel, "CreateToolhelp32Snapshot");
@@ -494,12 +494,29 @@ int RAND_poll(void)
* each entry. Consider each field a source of 1 byte
* of entropy.
*/
+ ZeroMemory(&hlist, sizeof(HEAPLIST32));
hlist.dwSize = sizeof(HEAPLIST32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
+ if (good) starttime = GetTickCount();
+#ifdef _MSC_VER
if (heaplist_first(handle, &hlist))
+ {
+ /*
+ following discussion on dev ML, exception on WinCE (or other Win
+ platform) is theoretically of unknown origin; prevent infinite
+ loop here when this theoretical case occurs; otherwise cope with
+ the expected (MSDN documented) exception-throwing behaviour of
+ Heap32Next() on WinCE.
+
+ based on patch in original message by Tanguy Fautré (2009/03/02)
+ Subject: RAND_poll() and CreateToolhelp32Snapshot() stability
+ */
+ int ex_cnt_limit = 42;
do
{
RAND_add(&hlist, hlist.dwSize, 3);
+ __try
+ {
+ ZeroMemory(&hentry, sizeof(HEAPENTRY32));
hentry.dwSize = sizeof(HEAPENTRY32);
if (heap_first(&hentry,
hlist.th32ProcessID,
@@ -510,10 +527,42 @@ int RAND_poll(void)
RAND_add(&hentry,
hentry.dwSize, 5);
while (heap_next(&hentry)
+ && (!good || (GetTickCount()-starttime)<MAXDELAY)
&& --entrycnt > 0);
}
- } while (heaplist_next(handle,
- &hlist) && GetTickCount() < stoptime);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* ignore access violations when walking the heap list */
+ ex_cnt_limit--;
+ }
+ } while (heaplist_next(handle, &hlist)
+ && (!good || (GetTickCount()-starttime)<MAXDELAY)
+ && ex_cnt_limit > 0);
+ }
+
+#else
+ if (heaplist_first(handle, &hlist))
+ {
+ do
+ {
+ RAND_add(&hlist, hlist.dwSize, 3);
+ hentry.dwSize = sizeof(HEAPENTRY32);
+ if (heap_first(&hentry,
+ hlist.th32ProcessID,
+ hlist.th32HeapID))
+ {
+ int entrycnt = 80;
+ do
+ RAND_add(&hentry,
+ hentry.dwSize, 5);
+ while (heap_next(&hentry)
+ && --entrycnt > 0);
+ }
+ } while (heaplist_next(handle, &hlist)
+ && (!good || (GetTickCount()-starttime)<MAXDELAY));
+ }
+#endif
/* process walking */
/* PROCESSENTRY32 contains 9 fields that will change
@@ -522,11 +571,11 @@ int RAND_poll(void)
*/
p.dwSize = sizeof(PROCESSENTRY32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
+ if (good) starttime = GetTickCount();
if (process_first(handle, &p))
do
RAND_add(&p, p.dwSize, 9);
- while (process_next(handle, &p) && GetTickCount() < stoptime);
+ while (process_next(handle, &p) && (!good || (GetTickCount()-starttime)<MAXDELAY));
/* thread walking */
/* THREADENTRY32 contains 6 fields that will change
@@ -534,11 +583,11 @@ int RAND_poll(void)
* 1 byte of entropy.
*/
t.dwSize = sizeof(THREADENTRY32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
+ if (good) starttime = GetTickCount();
if (thread_first(handle, &t))
do
RAND_add(&t, t.dwSize, 6);
- while (thread_next(handle, &t) && GetTickCount() < stoptime);
+ while (thread_next(handle, &t) && (!good || (GetTickCount()-starttime)<MAXDELAY));
/* module walking */
/* MODULEENTRY32 contains 9 fields that will change
@@ -546,12 +595,12 @@ int RAND_poll(void)
* 1 byte of entropy.
*/
m.dwSize = sizeof(MODULEENTRY32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
+ if (good) starttime = GetTickCount();
if (module_first(handle, &m))
do
RAND_add(&m, m.dwSize, 9);
while (module_next(handle, &m)
- && (GetTickCount() < stoptime));
+ && (!good || (GetTickCount()-starttime)<MAXDELAY));
if (close_snap)
close_snap(handle);
else