diff --git a/changes/bug16013 b/changes/bug16013 new file mode 100644 index 000000000..d194c609f --- /dev/null +++ b/changes/bug16013 @@ -0,0 +1,5 @@ + o Major bugfixes (hidden service, stability): + - Stop randomly crashing with an assertion failure when connecting to a + busy hidden service, or connecting to a hidden service while a NEWNYM + is in progress. Fixes bug 16013; bugfix on 0.1.0.1-rc. + diff --git a/changes/bug16360-failed-crypto-early-init b/changes/bug16360-failed-crypto-early-init new file mode 100644 index 000000000..21972bce5 --- /dev/null +++ b/changes/bug16360-failed-crypto-early-init @@ -0,0 +1,7 @@ + o Minor bugfixes (crypto error-handling): + - If crypto_early_init fails, a typo in a return value from tor_init + means that tor_main continues running, rather than returning + an error value. + Fixes bug 16360; bugfix on d3fb846d8c98 in 0.2.5.2-alpha, + introduced when implementing #4900. + Patch by "teor". diff --git a/changes/bug16363 b/changes/bug16363 new file mode 100644 index 000000000..1a6f8c6ef --- /dev/null +++ b/changes/bug16363 @@ -0,0 +1,4 @@ + o Minor bugfixes (Linux seccomp2 sandbox): + - Allow pipe() and pipe2() syscalls; we need these when eventfd2() + support is missing. Fixes bug 16363; bugfix on 0.2.6.3-alpha. + Patch from "teor". diff --git a/changes/bug16381 b/changes/bug16381 new file mode 100644 index 000000000..51a9b5300 --- /dev/null +++ b/changes/bug16381 @@ -0,0 +1,13 @@ + o Major bugfix (Hidden service client) + - Revert commit 9407040c592184e05e45a3c1a00739c2dd302288 of bug #14219 + that indeed fixed an issue but introduced a major hidden service + reachability regression detailed in bug #16381. This is a temporary + fix since we can live with the minor issue in #14219 but the + regression introduced is too much of a set back. + + To be clear, #14219 bug just results in some load on the network, and + some delay for the client when visiting a hidden service that will + ultimately fail. + + This is only a bandaid for #16381 thus it does _not_ fixes it. bugfix + on tor-0.2.6.3-alpha~138. diff --git a/changes/bug16400 b/changes/bug16400 new file mode 100644 index 000000000..3e5f9c584 --- /dev/null +++ b/changes/bug16400 @@ -0,0 +1,5 @@ + o Major bugfixes: + - Do not crash with an assertion error when parsing certain kinds + of malformed or truncated microdescriptors. Fixes bug 16400; + bugfix on 0.2.6.1-alpha. Found by "torkeln"; fix based on a patch by + "cypherpunks_backup". diff --git a/src/common/sandbox.c b/src/common/sandbox.c index cdb4521c8..161eab7aa 100644 --- a/src/common/sandbox.c +++ b/src/common/sandbox.c @@ -129,7 +129,15 @@ static int filter_nopar_gen[] = { SCMP_SYS(clone), SCMP_SYS(epoll_create), SCMP_SYS(epoll_wait), +#ifdef HAVE_EVENTFD SCMP_SYS(eventfd2), +#endif +#ifdef HAVE_PIPE2 + SCMP_SYS(pipe2), +#endif +#ifdef HAVE_PIPE + SCMP_SYS(pipe), +#endif SCMP_SYS(fcntl), SCMP_SYS(fstat), #ifdef __NR_fstat64 diff --git a/src/or/circuituse.c b/src/or/circuituse.c index d0d31ad9c..3b6f98266 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -2406,6 +2406,18 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn) return 1; } + /* At this point we need to re-check the state, since it's possible that + * our call to circuit_get_open_circ_or_launch() changed the connection's + * state from "CIRCUIT_WAIT" to "RENDDESC_WAIT" because we decided to + * re-fetch the descriptor. + */ + if (ENTRY_TO_CONN(conn)->state != AP_CONN_STATE_CIRCUIT_WAIT) { + log_info(LD_REND, "This connection is no longer ready to attach; its " + "state changed." + "(We probably have to re-fetch its descriptor.)"); + return 0; + } + if (rendcirc && (rendcirc->base_.purpose == CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED)) { log_info(LD_REND, diff --git a/src/or/main.c b/src/or/main.c index 8aa9a15fc..e53922218 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -2462,7 +2462,7 @@ tor_init(int argc, char *argv[]) /* Set up the crypto nice and early */ if (crypto_early_init() < 0) { log_err(LD_GENERAL, "Unable to initialize the crypto subsystem!"); - return 1; + return -1; } /* Initialize the history structures. */ diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index 5fdd13efc..6698f2fea 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -1249,12 +1249,18 @@ rend_cache_store_v2_desc_as_client(const char *desc, /* Do we already have a newer descriptor? */ tor_snprintf(key, sizeof(key), "2%s", service_id); e = (rend_cache_entry_t*) strmap_get_lc(rend_cache, key); - if (e && e->parsed->timestamp >= parsed->timestamp) { - log_info(LD_REND, "We already have a new enough service descriptor for " + if (e && e->parsed->timestamp > parsed->timestamp) { + log_info(LD_REND, "We already have a newer service descriptor for " "service ID %s with the same desc ID and version.", safe_str_client(service_id)); goto okay; } + /* Do we already have this descriptor? */ + if (e && !strcmp(desc, e->desc)) { + log_info(LD_REND,"We already have this service descriptor %s.", + safe_str_client(service_id)); + goto okay; + } if (!e) { e = tor_malloc_zero(sizeof(rend_cache_entry_t)); strmap_set_lc(rend_cache, key, e); diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 9c6651292..dcf419798 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2001 Matej Pfajfar. + /* Copyright (c) 2001 Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. * Copyright (c) 2007-2015, The Tor Project, Inc. */ @@ -4165,7 +4165,10 @@ microdescs_parse_from_string(const char *s, const char *eos, { const char *cp = tor_memstr(s, start_of_next_microdesc-s, "onion-key"); - tor_assert(cp); + const int no_onion_key = (cp == NULL); + if (no_onion_key) { + cp = s; /* So that we have *some* junk to put in the body */ + } md->bodylen = start_of_next_microdesc - cp; md->saved_location = where; @@ -4174,8 +4177,13 @@ microdescs_parse_from_string(const char *s, const char *eos, else md->body = (char*)cp; md->off = cp - start; + crypto_digest256(md->digest, md->body, md->bodylen, DIGEST_SHA256); + if (no_onion_key) { + log_fn(LOG_PROTOCOL_WARN, LD_DIR, "Malformed or truncated descriptor"); + goto next; + } } - crypto_digest256(md->digest, md->body, md->bodylen, DIGEST_SHA256); + if (tokenize_string(area, s, start_of_next_microdesc, tokens, microdesc_token_table, flags)) { diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c index fb3df77ed..c0376348d 100644 --- a/src/test/test_microdesc.c +++ b/src/test/test_microdesc.c @@ -713,12 +713,46 @@ test_md_reject_cache(void *arg) tor_free(mock_ns_val); } +static void +test_md_corrupt_desc(void *arg) +{ + char *cp = NULL; + smartlist_t *sl = NULL; + (void) arg; + + sl = microdescs_add_to_cache(get_microdesc_cache(), + "@last-listed 2015-06-22 10:00:00\n" + "onion-k\n", + NULL, SAVED_IN_JOURNAL, 0, time(NULL), NULL); + tt_int_op(smartlist_len(sl), ==, 0); + smartlist_free(sl); + + sl = microdescs_add_to_cache(get_microdesc_cache(), + "@last-listed 2015-06-22 10:00:00\n" + "wiggly\n", + NULL, SAVED_IN_JOURNAL, 0, time(NULL), NULL); + tt_int_op(smartlist_len(sl), ==, 0); + smartlist_free(sl); + + tor_asprintf(&cp, "%s\n%s", test_md1, "@foobar\nonion-wobble\n"); + + sl = microdescs_add_to_cache(get_microdesc_cache(), + cp, cp+strlen(cp), + SAVED_IN_JOURNAL, 0, time(NULL), NULL); + tt_int_op(smartlist_len(sl), ==, 0); + smartlist_free(sl); + + done: + tor_free(cp); +} + struct testcase_t microdesc_tests[] = { { "cache", test_md_cache, TT_FORK, NULL, NULL }, { "broken_cache", test_md_cache_broken, TT_FORK, NULL, NULL }, { "generate", test_md_generate, 0, NULL, NULL }, { "parse", test_md_parse, 0, NULL, NULL }, { "reject_cache", test_md_reject_cache, TT_FORK, NULL, NULL }, + { "corrupt_desc", test_md_corrupt_desc, TT_FORK, NULL, NULL }, END_OF_TESTCASES };