[or-cvs] r14150: Use RAND_poll() again: the bug that made us stop using it ha (in tor/trunk: . src/common src/or)

nickm at seul.org nickm at seul.org
Fri Mar 21 19:18:58 UTC 2008


Author: nickm
Date: 2008-03-21 15:18:57 -0400 (Fri, 21 Mar 2008)
New Revision: 14150

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/src/common/crypto.c
   tor/trunk/src/common/crypto.h
   tor/trunk/src/or/main.c
Log:
 r19004 at catbus:  nickm | 2008-03-21 15:18:43 -0400
 Use RAND_poll() again: the bug that made us stop using it has been fixed.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r19004] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2008-03-21 19:18:54 UTC (rev 14149)
+++ tor/trunk/ChangeLog	2008-03-21 19:18:57 UTC (rev 14150)
@@ -24,6 +24,13 @@
     - Add a couple of extra warnings to --enable-gcc-warnings for GCC 4.3,
       and stop using a warning that had become unfixably verbose under GCC
       4.3.
+    - Start using OpenSSL's RAND_poll() for better (and more portable)
+      cross-platform entropy collection again.  We used to use it, then
+      stopped using it because of a bug that could crash systems that called
+      RAND_poll when they had a lot of fds open.  It looks like the bug got
+      fixed in late 2006.  Our new behavior is to call RAND_poll() at
+      startup, and to call RAND_poll() when we reseed later only if we
+      have a non-buggy OpenSSL version.
 
   o Code simplifications and refactoring:
     - Refactor code using connection_ap_handshake_attach_circuit() to

Modified: tor/trunk/src/common/crypto.c
===================================================================
--- tor/trunk/src/common/crypto.c	2008-03-21 19:18:54 UTC (rev 14149)
+++ tor/trunk/src/common/crypto.c	2008-03-21 19:18:57 UTC (rev 14150)
@@ -1667,19 +1667,29 @@
 
 /* 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 @@
   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

Modified: tor/trunk/src/common/crypto.h
===================================================================
--- tor/trunk/src/common/crypto.h	2008-03-21 19:18:54 UTC (rev 14149)
+++ tor/trunk/src/common/crypto.h	2008-03-21 19:18:57 UTC (rev 14150)
@@ -166,7 +166,7 @@
                                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);

Modified: tor/trunk/src/or/main.c
===================================================================
--- tor/trunk/src/or/main.c	2008-03-21 19:18:54 UTC (rev 14149)
+++ tor/trunk/src/or/main.c	2008-03-21 19:18:57 UTC (rev 14150)
@@ -900,7 +900,7 @@
   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 @@
 #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;
   }



More information about the tor-commits mailing list