summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2008-03-21 19:18:57 +0000
committerNick Mathewson <nickm@torproject.org>2008-03-21 19:18:57 +0000
commitb5b77f8bf37a193f23c5b68f688f6175266a612f (patch)
tree644390476138db18724699ab2f04f9c7bbe3729b /src
parent64f38f217ae21eaa00b48749353dad62cfcb72c6 (diff)
downloadtor-b5b77f8bf37a193f23c5b68f688f6175266a612f.tar.gz
tor-b5b77f8bf37a193f23c5b68f688f6175266a612f.zip
r19004@catbus: nickm | 2008-03-21 15:18:43 -0400
Use RAND_poll() again: the bug that made us stop using it has been fixed. svn:r14150
Diffstat (limited to 'src')
-rw-r--r--src/common/crypto.c38
-rw-r--r--src/common/crypto.h2
-rw-r--r--src/or/main.c4
3 files changed, 27 insertions, 17 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c
index ea70aad4ab..44fa3b2b40 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -1667,19 +1667,29 @@ crypto_dh_free(crypto_dh_env_t *dh)
/* Use RAND_poll if openssl is 0.9.6 release or later. (The "f" means
"release".) */
-//#define USE_RAND_POLL (OPENSSL_VERSION_NUMBER >= 0x0090600fl)
-#define USE_RAND_POLL 0
-/* XXX Somehow setting USE_RAND_POLL on causes stack smashes. We're
- * not sure where. This was the big bug with Tor 0.1.1.9-alpha. */
+#define HAVE_RAND_POLL (OPENSSL_VERSION_NUMBER >= 0x0090600fl)
-/** Seed OpenSSL's random number generator with bytes from the
- * operating system. Return 0 on success, -1 on failure.
+/* Versions of openssl prior to 0.9.7k and 0.9.8c had a bug where RAND_poll
+ * would allocate an fd_set on the stack, open a new file, and try to FD_SET
+ * that fd without checking whether it fit in the fd_set. Thus, if the
+ * system has not just been started up, it is unsafe to call */
+#define RAND_POLL_IS_SAFE \
+ ((OPENSSL_VERSION_NUMBER >= 0x009070afl && \
+ OPENSSL_VERSION_NUMBER <= 0x00907fffl) || \
+ (OPENSSL_VERSION_NUMBER >= 0x0090803fl))
+
+/* We could actually get away with calling RAND_poll */
+#define USE_RAND_POLL (HAVE_RAND_POLL && RAND_POLL_IS_SAFE)
+
+/** Seed OpenSSL's random number generator with bytes from the operating
+ * system. <b>startup</b> should be true iff we have just started Tor and
+ * have not yet allocated a bunch of fds. Return 0 on success, -1 on failure.
*/
int
-crypto_seed_rng(void)
+crypto_seed_rng(int startup)
{
char buf[ADD_ENTROPY];
- int rand_poll_status;
+ int rand_poll_status = 0;
/* local variables */
#ifdef MS_WINDOWS
@@ -1693,15 +1703,15 @@ crypto_seed_rng(void)
size_t n;
#endif
-#if USE_RAND_POLL
+#if HAVE_RAND_POLL
/* OpenSSL 0.9.6 adds a RAND_poll function that knows about more kinds of
* entropy than we do. We'll try calling that, *and* calling our own entropy
* functions. If one succeeds, we'll accept the RNG as seeded. */
- rand_poll_status = RAND_poll();
- if (rand_poll_status == 0)
- log_warn(LD_CRYPTO, "RAND_poll() failed.");
-#else
- rand_poll_status = 0;
+ if (startup || RAND_POLL_IS_SAFE) {
+ rand_poll_status = RAND_poll();
+ if (rand_poll_status == 0)
+ log_warn(LD_CRYPTO, "RAND_poll() failed.");
+ }
#endif
#ifdef MS_WINDOWS
diff --git a/src/common/crypto.h b/src/common/crypto.h
index e51c0777a9..2627335113 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -166,7 +166,7 @@ int crypto_expand_key_material(const char *key_in, size_t in_len,
char *key_out, size_t key_out_len);
/* random numbers */
-int crypto_seed_rng(void);
+int crypto_seed_rng(int startup);
int crypto_rand(char *to, size_t n);
int crypto_rand_int(unsigned int max);
uint64_t crypto_rand_uint64(uint64_t max);
diff --git a/src/or/main.c b/src/or/main.c
index 396b6f3b91..5630f4efe8 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -900,7 +900,7 @@ run_scheduled_events(time_t now)
if (time_to_add_entropy < now) {
if (time_to_add_entropy) {
/* We already seeded once, so don't die on failure. */
- crypto_seed_rng();
+ crypto_seed_rng(0);
}
/** How often do we add more entropy to OpenSSL's RNG pool? */
#define ENTROPY_INTERVAL (60*60)
@@ -1810,7 +1810,7 @@ tor_init(int argc, char *argv[])
#endif
crypto_global_init(get_options()->HardwareAccel);
- if (crypto_seed_rng()) {
+ if (crypto_seed_rng(1)) {
log_err(LD_BUG, "Unable to seed random number generator. Exiting.");
return -1;
}