aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2013-12-22 02:25:53 -0500
committerRoger Dingledine <arma@torproject.org>2013-12-22 02:25:53 -0500
commit2349833f71941e96a1bbdcf22c4645cef4ac3ced (patch)
tree897e809ea8828bc6762031e1a2e9afd312c3d846
parente719d05fd296a9dd59af9becb21ef3ff1c426b3c (diff)
parent2c956f0c99beed22ada43ba9458302308af87884 (diff)
downloadtor-2349833f71941e96a1bbdcf22c4645cef4ac3ced.tar.gz
tor-2349833f71941e96a1bbdcf22c4645cef4ac3ced.zip
Merge branch 'maint-0.2.4' into release-0.2.4
-rw-r--r--changes/bug1040211
-rw-r--r--changes/bug104093
-rw-r--r--changes/bug104234
-rw-r--r--changes/bug104566
-rw-r--r--src/common/crypto.c13
-rw-r--r--src/or/circuituse.c2
-rw-r--r--src/or/dirvote.c3
-rw-r--r--src/or/microdesc.c36
-rw-r--r--src/or/routerparse.c13
-rw-r--r--src/or/routerparse.h2
-rw-r--r--src/test/test_microdesc.c45
11 files changed, 116 insertions, 22 deletions
diff --git a/changes/bug10402 b/changes/bug10402
new file mode 100644
index 0000000000..eac00bdc6d
--- /dev/null
+++ b/changes/bug10402
@@ -0,0 +1,11 @@
+ o Major bugfixes:
+ - Do not allow OpenSSL engines to replace the PRNG, even when
+ HardwareAccel is set. The only default builtin PRNG engine uses
+ the Intel RDRAND instruction to replace the entire PRNG, and
+ ignores all attempts to seed it with more entropy. That's
+ cryptographically stupid: the right response to a new alleged
+ entropy source is never to discard all previously used entropy
+ sources. Fixes bug 10402; works around behavior introduced in
+ OpenSSL 1.0.0. Diagnosis and investigation thanks to "coderman"
+ and "rl1987".
+
diff --git a/changes/bug10409 b/changes/bug10409
new file mode 100644
index 0000000000..5ef5ae29de
--- /dev/null
+++ b/changes/bug10409
@@ -0,0 +1,3 @@
+ o Minor bugfixes:
+ - Avoid a crash bug when starting with a corrupted microdescriptor
+ cache file. Fix for bug 10406; bugfix on 0.2.2.6-alpha.
diff --git a/changes/bug10423 b/changes/bug10423
new file mode 100644
index 0000000000..493b7b15e3
--- /dev/null
+++ b/changes/bug10423
@@ -0,0 +1,4 @@
+ o Minor bugfixes:
+ - If we fail to dump a previously cached microdescriptor to disk, avoid
+ freeing duplicate data later on. Fix for bug 10423; bugfix on
+ 0.2.4.13-alpha. Spotted by "bobnomnom".
diff --git a/changes/bug10456 b/changes/bug10456
new file mode 100644
index 0000000000..fb3b92fcd8
--- /dev/null
+++ b/changes/bug10456
@@ -0,0 +1,6 @@
+ o Major bugfixes:
+ - Avoid launching spurious extra circuits when a stream is pending.
+ This fixes a bug where any circuit that _wasn't_ unusable for new
+ streams would be treated as if it were, causing extra circuits to
+ be launched. Fixes bug 10456; bugfix on 0.2.4.12-alpha.
+
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 0ababeaea5..940a756f61 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -169,8 +169,8 @@ log_engine(const char *fn, ENGINE *e)
const char *name, *id;
name = ENGINE_get_name(e);
id = ENGINE_get_id(e);
- log_notice(LD_CRYPTO, "Using OpenSSL engine %s [%s] for %s",
- name?name:"?", id?id:"?", fn);
+ log_notice(LD_CRYPTO, "Default OpenSSL engine for %s is %s [%s]",
+ fn, name?name:"?", id?id:"?");
} else {
log_info(LD_CRYPTO, "Using default implementation for %s", fn);
}
@@ -288,7 +288,7 @@ crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
}
log_engine("RSA", ENGINE_get_default_RSA());
log_engine("DH", ENGINE_get_default_DH());
- log_engine("RAND", ENGINE_get_default_RAND());
+ log_engine("RAND (which we will not use)", ENGINE_get_default_RAND());
log_engine("SHA1", ENGINE_get_digest_engine(NID_sha1));
log_engine("3DES", ENGINE_get_cipher_engine(NID_des_ede3_ecb));
log_engine("AES", ENGINE_get_cipher_engine(NID_aes_128_ecb));
@@ -297,6 +297,13 @@ crypto_global_init(int useAccel, const char *accelName, const char *accelDir)
log_info(LD_CRYPTO, "NOT using OpenSSL engine support.");
}
+ if (RAND_get_rand_method() != RAND_SSLeay()) {
+ log_notice(LD_CRYPTO, "It appears that one of our engines has provided "
+ "a replacement the OpenSSL RNG. Resetting it to the default "
+ "implementation.");
+ RAND_set_rand_method(RAND_SSLeay());
+ }
+
evaluate_evp_for_aes(-1);
evaluate_ctr_for_aes();
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 25997ebdbe..5984691989 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -828,7 +828,7 @@ circuit_stream_is_being_handled(entry_connection_t *conn,
cpath_build_state_t *build_state = origin_circ->build_state;
if (build_state->is_internal || build_state->onehop_tunnel)
continue;
- if (!origin_circ->unusable_for_new_conns)
+ if (origin_circ->unusable_for_new_conns)
continue;
exitnode = build_state_get_exit_node(build_state);
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index e0af66e22d..c6d1244902 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -3585,7 +3585,8 @@ dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method)
{
smartlist_t *lst = microdescs_parse_from_string(output,
- output+strlen(output), 0, 1);
+ output+strlen(output), 0,
+ SAVED_NOWHERE);
if (smartlist_len(lst) != 1) {
log_warn(LD_DIR, "We generated a microdescriptor we couldn't parse.");
SMARTLIST_FOREACH(lst, microdesc_t *, md, microdesc_free(md));
diff --git a/src/or/microdesc.c b/src/or/microdesc.c
index 8b5581f4af..90ac0ac649 100644
--- a/src/or/microdesc.c
+++ b/src/or/microdesc.c
@@ -154,11 +154,10 @@ microdescs_add_to_cache(microdesc_cache_t *cache,
{
smartlist_t *descriptors, *added;
const int allow_annotations = (where != SAVED_NOWHERE);
- const int copy_body = (where != SAVED_IN_CACHE);
descriptors = microdescs_parse_from_string(s, eos,
allow_annotations,
- copy_body);
+ where);
if (listed_at > 0) {
SMARTLIST_FOREACH(descriptors, microdesc_t *, md,
md->last_listed = listed_at);
@@ -407,6 +406,26 @@ should_rebuild_md_cache(microdesc_cache_t *cache)
return 0;
}
+/**
+ * Mark <b>md</b> as having no body, and release any storage previously held
+ * by its body.
+ */
+static void
+microdesc_wipe_body(microdesc_t *md)
+{
+ if (!md)
+ return;
+
+ if (md->saved_location != SAVED_IN_CACHE)
+ tor_free(md->body);
+
+ md->off = 0;
+ md->saved_location = SAVED_NOWHERE;
+ md->body = NULL;
+ md->bodylen = 0;
+ md->no_save = 1;
+}
+
/** Regenerate the main cache file for <b>cache</b>, clear the journal file,
* and update every microdesc_t in the cache with pointers to its new
* location. If <b>force</b> is true, do this unconditionally. If
@@ -455,12 +474,7 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
size = dump_microdescriptor(fd, md, &annotation_len);
if (size < 0) {
- if (md->saved_location != SAVED_IN_CACHE)
- tor_free(md->body);
- md->saved_location = SAVED_NOWHERE;
- md->off = 0;
- md->bodylen = 0;
- md->no_save = 1;
+ microdesc_wipe_body(md);
/* rewind, in case it was a partial write. */
tor_fd_setpos(fd, off);
@@ -497,11 +511,7 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
HT_FOREACH(mdp, microdesc_map, &cache->map) {
microdesc_t *md = *mdp;
if (md->saved_location == SAVED_IN_CACHE) {
- md->off = 0;
- md->saved_location = SAVED_NOWHERE;
- md->body = NULL;
- md->bodylen = 0;
- md->no_save = 1;
+ microdesc_wipe_body(md);
}
}
return -1;
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 890d59660a..3aa4bdf8a5 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -4245,12 +4245,17 @@ find_start_of_next_microdesc(const char *s, const char *eos)
/** Parse as many microdescriptors as are found from the string starting at
* <b>s</b> and ending at <b>eos</b>. If allow_annotations is set, read any
- * annotations we recognize and ignore ones we don't. If <b>copy_body</b> is
- * true, then strdup the bodies of the microdescriptors. Return all newly
+ * annotations we recognize and ignore ones we don't.
+ *
+ * If <b>saved_location</b> isn't SAVED_IN_CACHE, make a local copy of each
+ * descriptor in the body field of each microdesc_t.
+ *
+ * Return all newly
* parsed microdescriptors in a newly allocated smartlist_t. */
smartlist_t *
microdescs_parse_from_string(const char *s, const char *eos,
- int allow_annotations, int copy_body)
+ int allow_annotations,
+ saved_location_t where)
{
smartlist_t *tokens;
smartlist_t *result;
@@ -4259,6 +4264,7 @@ microdescs_parse_from_string(const char *s, const char *eos,
const char *start = s;
const char *start_of_next_microdesc;
int flags = allow_annotations ? TS_ANNOTATIONS_OK : 0;
+ const int copy_body = (where != SAVED_IN_CACHE);
directory_token_t *tok;
@@ -4288,6 +4294,7 @@ microdescs_parse_from_string(const char *s, const char *eos,
tor_assert(cp);
md->bodylen = start_of_next_microdesc - cp;
+ md->saved_location = where;
if (copy_body)
md->body = tor_memdup_nulterm(cp, md->bodylen);
else
diff --git a/src/or/routerparse.h b/src/or/routerparse.h
index c65cdc996c..eb2e885cb1 100644
--- a/src/or/routerparse.h
+++ b/src/or/routerparse.h
@@ -64,7 +64,7 @@ ns_detached_signatures_t *networkstatus_parse_detached_signatures(
smartlist_t *microdescs_parse_from_string(const char *s, const char *eos,
int allow_annotations,
- int copy_body);
+ saved_location_t where);
authority_cert_t *authority_cert_parse_from_string(const char *s,
const char **end_of_string);
diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c
index a8171a325c..53a03a48ad 100644
--- a/src/test/test_microdesc.c
+++ b/src/test/test_microdesc.c
@@ -240,8 +240,53 @@ test_md_cache(void *data)
tor_free(fn);
}
+static const char truncated_md[] =
+ "@last-listed 2013-08-08 19:02:59\n"
+ "onion-key\n"
+ "-----BEGIN RSA PUBLIC KEY-----\n"
+ "MIGJAoGBAM91vLFNaM+gGhnRIdz2Cm/Kl7Xz0cOobIdVzhS3cKUJfk867hCuTipS\n"
+ "NveLBzNopvgXKruAAzEj3cACxk6Q8lv5UWOGCD1UolkgsWSE62RBjap44g+oc9J1\n"
+ "RI9968xOTZw0VaBQg9giEILNXl0djoikQ+5tQRUvLDDa67gpa5Q1AgMBAAE=\n"
+ "-----END RSA PUBLIC KEY-----\n"
+ "family @\n";
+
+static void
+test_md_cache_broken(void *data)
+{
+ or_options_t *options;
+ char *fn=NULL;
+ microdesc_cache_t *mc = NULL;
+
+ (void)data;
+
+ options = get_options_mutable();
+ tt_assert(options);
+ options->DataDirectory = tor_strdup(get_fname("md_datadir_test2"));
+
+#ifdef _WIN32
+ tt_int_op(0, ==, mkdir(options->DataDirectory));
+#else
+ tt_int_op(0, ==, mkdir(options->DataDirectory, 0700));
+#endif
+
+ tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs",
+ options->DataDirectory);
+
+ write_str_to_file(fn, truncated_md, 1);
+
+ mc = get_microdesc_cache();
+ tt_assert(mc);
+
+ done:
+ if (options)
+ tor_free(options->DataDirectory);
+ tor_free(fn);
+ microdesc_free_all();
+}
+
struct testcase_t microdesc_tests[] = {
{ "cache", test_md_cache, TT_FORK, NULL, NULL },
+ { "broken_cache", test_md_cache_broken, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};