From 59fa0c2d996621af5c6990534fe9a07864882975 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 15 Jun 2015 10:13:11 -0400 Subject: [PATCH 1/5] Fix another seccomp2 issue 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". --- changes/bug16363 | 4 ++++ src/common/sandbox.c | 8 ++++++++ 2 files changed, 12 insertions(+) create mode 100644 changes/bug16363 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/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 From 8acf5255c20c667f32313ee672c85f6ae00a4f87 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Tue, 16 Jun 2015 13:16:34 -0400 Subject: [PATCH 2/5] Revert "Do not replace a HS descriptor with a different replica of itself" This reverts commit 9407040c592184e05e45a3c1a00739c2dd302288. Small fix, "e->received" had to be removed since that variable doesn't exist anymore. Signed-off-by: David Goulet --- changes/bug16381 | 13 +++++++++++++ src/or/rendcommon.c | 10 ++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 changes/bug16381 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/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); From 75388f67c07d1a48c6fb9c5d1c4441ab66b644c0 Mon Sep 17 00:00:00 2001 From: teor Date: Sat, 13 Jun 2015 21:28:02 +1000 Subject: [PATCH 3/5] Correctly handle failed crypto_early_init 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". --- changes/bug16360-failed-crypto-early-init | 7 +++++++ src/or/main.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 changes/bug16360-failed-crypto-early-init 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/src/or/main.c b/src/or/main.c index 9c1cabf03..031f758f4 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -2346,7 +2346,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. */ From e0b7598833238766b157f8eb799f448dac4c1283 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 22 Jun 2015 13:51:56 -0400 Subject: [PATCH 4/5] Repair breakage in early-error case of microdesc parsing When I fixed #11243, I made it so we would take the digest of a descriptor before tokenizing it, so we could desist from download attempts if parsing failed. But when I did that, I didn't remove an assertion that the descriptor began with "onion-key". Usually, this was enforced by "find_start_of_next_microdescriptor", but when find_start_of_next_microdescriptor returned NULL, the assertion was triggered. Fixes bug 16400. Thanks to torkeln for reporting and cypherpunks_backup for diagnosing and writing the first fix here. --- changes/bug16400 | 5 +++++ src/or/routerparse.c | 14 +++++++++++--- src/test/test_microdesc.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 changes/bug16400 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/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 }; From 68eaaed7982b63abedfcfba33f7e2656c68e3e4a Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 25 Jun 2015 11:10:43 -0400 Subject: [PATCH 5/5] Avoid crashing on busy/NEWNYM+hidden service clients When we ran out of intro points for a hidden service (which could happen on a newnym), we would change the connection's state back to "waiting for hidden service descriptor." But this would make an assertion fail if we went on to call circuit_get_open_circ_or_launch again. This fixes bug 16013; I believe the bug was introduced in 38be533c69417aacf28cedec1c3bae808ce29f4, where we made it possible for circuit_get_open_circ_or_launch() to change the connection's state. --- changes/bug16013 | 5 +++++ src/or/circuituse.c | 12 ++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 changes/bug16013 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/src/or/circuituse.c b/src/or/circuituse.c index 714754a67..75cd4fec5 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -2346,6 +2346,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,