From: Nick Mathewson <nickm@torproject.org>
Date: Mon, 19 Aug 2013 13:52:29 +0000 (-0400)
Subject: Really remove RNG seeds from the stack
X-Git-Tag: release-2.0.22-stable~27^2
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f5ced88cec292a8310c0f87748bad87686960ba8;p=libevent

Really remove RNG seeds from the stack
---

diff --git a/arc4random.c b/arc4random.c
index 7a6c4ff5..39773399 100644
--- a/arc4random.c
+++ b/arc4random.c
@@ -161,7 +161,7 @@ arc4_seed_win32(void)
 	if (!CryptGenRandom(provider, sizeof(buf), buf))
 		return -1;
 	arc4_addrandom(buf, sizeof(buf));
-	memset(buf, 0, sizeof(buf));
+	evutil_memclear_(buf, sizeof(buf));
 	arc4_seeded_ok = 1;
 	return 0;
 }
@@ -199,7 +199,7 @@ arc4_seed_sysctl_linux(void)
 		return -1;
 
 	arc4_addrandom(buf, sizeof(buf));
-	memset(buf, 0, sizeof(buf));
+	evutil_memclear_(buf, sizeof(buf));
 	arc4_seeded_ok = 1;
 	return 0;
 }
@@ -239,7 +239,7 @@ arc4_seed_sysctl_bsd(void)
 		return -1;
 
 	arc4_addrandom(buf, sizeof(buf));
-	memset(buf, 0, sizeof(buf));
+	evutil_memclear_(buf, sizeof(buf));
 	arc4_seeded_ok = 1;
 	return 0;
 }
@@ -284,8 +284,8 @@ arc4_seed_proc_sys_kernel_random_uuid(void)
 		arc4_addrandom(entropy, nybbles/2);
 		bytes += nybbles/2;
 	}
-	memset(entropy, 0, sizeof(entropy));
-	memset(buf, 0, sizeof(buf));
+	evutil_memclear_(entropy, sizeof(entropy));
+	evutil_memclear_(buf, sizeof(buf));
 	arc4_seeded_ok = 1;
 	return 0;
 }
@@ -309,7 +309,7 @@ static int arc4_seed_urandom_helper_(const char *fname)
 	if (n != sizeof(buf))
 		return -1;
 	arc4_addrandom(buf, sizeof(buf));
-	memset(buf, 0, sizeof(buf));
+	evutil_memclear_(buf, sizeof(buf));
 	arc4_seeded_ok = 1;
 	return 0;
 }
diff --git a/evutil.c b/evutil.c
index b9521ec6..33445170 100644
--- a/evutil.c
+++ b/evutil.c
@@ -2109,6 +2109,18 @@ _evutil_weakrand(void)
 #endif
 }
 
+/**
+ * Volatile pointer to memset: we use this to keep the compiler from
+ * eliminating our call to memset.
+ */
+void * (*volatile evutil_memset_volatile_)(void *, int, size_t) = memset;
+
+void
+evutil_memclear_(void *mem, size_t len)
+{
+	evutil_memset_volatile_(mem, 0, len);
+}
+
 int
 evutil_sockaddr_is_loopback(const struct sockaddr *addr)
 {
diff --git a/util-internal.h b/util-internal.h
index 538f1fe3..01ebc171 100644
--- a/util-internal.h
+++ b/util-internal.h
@@ -320,6 +320,8 @@ HANDLE evutil_load_windows_system_library(const TCHAR *library_name);
 #endif
 #endif
 
+void evutil_memclear_(void *mem, size_t len);
+
 #ifdef __cplusplus
 }
 #endif