From 85ff6f9114eb2d492d88ed55d01a69f7bafb10be Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 11 Apr 2019 18:18:14 -0400 Subject: [PATCH 01/12] Fix a memory leak on failure to create keys directory. Fixes bug 30148, which is also CID 1437429 and CID 1437454. Bugfix on 0.3.3.1-alpha, when separate key directories became a thing. --- changes/bug30148 | 4 ++++ src/or/routerkeys.c | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 changes/bug30148 diff --git a/changes/bug30148 b/changes/bug30148 new file mode 100644 index 0000000000..7d0257e3fe --- /dev/null +++ b/changes/bug30148 @@ -0,0 +1,4 @@ + o Minor bugfixes (memory leak): + - Avoid a minor memory leak that could occur on relays when + creating a keys directory failed. Fixes bug 30148; bugfix on + 0.3.3.1-alpha. diff --git a/src/or/routerkeys.c b/src/or/routerkeys.c index 43460da8cc..dd19d28d05 100644 --- a/src/or/routerkeys.c +++ b/src/or/routerkeys.c @@ -816,7 +816,7 @@ load_ed_keys(const or_options_t *options, time_t now) /* Check/Create the key directory */ if (create_keys_directory(options) < 0) - return -1; + goto err; char *fname; if (options->master_key_fname) { @@ -1403,4 +1403,3 @@ routerkeys_free_all(void) rsa_ed_crosscert = NULL; // redundant rsa_ed_crosscert_len = 0; } - From 8c4e68438dd680b6b36f9b337b12d098b08db9d8 Mon Sep 17 00:00:00 2001 From: "Bernhard M. Wiedemann" Date: Mon, 15 Apr 2019 13:57:24 +0200 Subject: [PATCH 02/12] Do not warn about compatible OpenSSL upgrades When releasing OpenSSL patch-level maintenance updates, we do not want to rebuild binaries using it. And since they guarantee ABI stability, we do not have to. Without this patch, warning messages were produced that confused users: https://bugzilla.opensuse.org/show_bug.cgi?id=1129411 Fixes bug 30190; bugfix on 0.2.4.2-alpha commit 7607ad2bec Signed-off-by: Bernhard M. Wiedemann --- changes/bug30190 | 3 +++ src/lib/crypt_ops/crypto_openssl_mgt.c | 8 ++++++++ 2 files changed, 11 insertions(+) create mode 100644 changes/bug30190 diff --git a/changes/bug30190 b/changes/bug30190 new file mode 100644 index 0000000000..e2352c3b9c --- /dev/null +++ b/changes/bug30190 @@ -0,0 +1,3 @@ + o Minor bugfixes (lib): + do not log a warning for OpenSSL versions that should be compatible + Fixes bug 30190; bugfix on 0.2.4.2-alpha diff --git a/src/lib/crypt_ops/crypto_openssl_mgt.c b/src/lib/crypt_ops/crypto_openssl_mgt.c index 60e4ea795e..c97815f9a4 100644 --- a/src/lib/crypt_ops/crypto_openssl_mgt.c +++ b/src/lib/crypt_ops/crypto_openssl_mgt.c @@ -213,6 +213,14 @@ crypto_openssl_early_init(void) !strcmp(version_str, OPENSSL_VERSION_TEXT)) { log_info(LD_CRYPTO, "OpenSSL version matches version from headers " "(%lx: %s).", version_num, version_str); + } else if ((version_num & 0xffff0000) == + (OPENSSL_VERSION_NUMBER & 0xffff0000)) { + log_notice(LD_CRYPTO, + "We compiled with OpenSSL %lx: %s and we " + "are running with OpenSSL %lx: %s. " + "These two versions should be binary compatible.", + (unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT, + version_num, version_str); } else { log_warn(LD_CRYPTO, "OpenSSL version from headers does not match the " "version we're running with. If you get weird crashes, that " From 37aae23945c45c459091b38699130a14466d33ef Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 17 May 2019 10:03:41 -0400 Subject: [PATCH 03/12] OOM-purge the DNS cache one part at a time Previously we purged it in 1-hour increments -- but one-hour is the maximum TTL for the cache! Now we do it in 25%-TTL increments. Fixes bug 29617; bugfix on 0.3.5.1-alpha. --- changes/ticket29617 | 4 ++++ src/feature/relay/dns.c | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changes/ticket29617 diff --git a/changes/ticket29617 b/changes/ticket29617 new file mode 100644 index 0000000000..4d50ea9627 --- /dev/null +++ b/changes/ticket29617 @@ -0,0 +1,4 @@ + o Minor bugfixes (out-of-memory handler): + - When purging the DNS cache because of an out-of-memory condition, + try purging just the older entries at first. Previously, we would + purge the whole thing. Fixes bug 29617; bugfix on 0.3.5.1-alpha. diff --git a/src/feature/relay/dns.c b/src/feature/relay/dns.c index d3660c47ef..cc9f4cf490 100644 --- a/src/feature/relay/dns.c +++ b/src/feature/relay/dns.c @@ -2130,7 +2130,8 @@ dns_cache_handle_oom(time_t now, size_t min_remove_bytes) current_size -= bytes_removed; total_bytes_removed += bytes_removed; - time_inc += 3600; /* Increase time_inc by 1 hour. */ + /* Increase time_inc by a reasonable fraction. */ + time_inc += (MAX_DNS_TTL_AT_EXIT / 4); } while (total_bytes_removed < min_remove_bytes); return total_bytes_removed; From 7971b3a5a6fc8b964339b144ae33faf9db1c3869 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 25 May 2019 03:55:24 +0000 Subject: [PATCH 04/12] Use MAP_INHERIT_ZERO or MAP_INHERIT_NONE if available. Fixes assertion failure in tests on NetBSD: slow/prob_distr/stochastic_log_logistic: [forking] May 25 03:56:58.091 [err] tor_assertion_failed_(): Bug: src/lib/crypt_ops/crypto_rand_fast.c:184: crypto_fast_rng_new_from_seed: Assertion inherit != INHERIT_RES_KEEP failed; aborting. (on Tor 0.4.1.1-alpha-dev 29955f13e5bc8e61) May 25 03:56:58.091 [err] Bug: Assertion inherit != INHERIT_RES_KEEP failed in crypto_fast_rng_new_from_seed at src/lib/crypt_ops/crypto_rand_fast.c:184: . (Stack trace not available) (on Tor 0.4.1.1-alpha-dev 29955f13e5bc8e61) [Lost connection!] --- src/lib/malloc/map_anon.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib/malloc/map_anon.c b/src/lib/malloc/map_anon.c index 2fc6e89ea2..2430f7ad11 100644 --- a/src/lib/malloc/map_anon.c +++ b/src/lib/malloc/map_anon.c @@ -50,11 +50,15 @@ #ifdef INHERIT_ZERO #define FLAG_ZERO INHERIT_ZERO +#elif defined(MAP_INHERIT_ZERO) +#define FLAG_ZERO MAP_INHERIT_ZERO #endif #ifdef INHERIT_NONE #define FLAG_NOINHERIT INHERIT_NONE #elif defined(VM_INHERIT_NONE) #define FLAG_NOINHERIT VM_INHERIT_NONE +#elif defined(MAP_INHERIT_NONE) +#define FLAG_NOINHERIT MAP_INHERIT_NONE #endif #elif defined(HAVE_MADVISE) From bdf685e47614ef5dca935b9fe9a608ffdd63a816 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 29 May 2019 09:05:26 -0400 Subject: [PATCH 05/12] Changes file for bug 30614 --- changes/bug30614 | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changes/bug30614 diff --git a/changes/bug30614 b/changes/bug30614 new file mode 100644 index 0000000000..9f904bd115 --- /dev/null +++ b/changes/bug30614 @@ -0,0 +1,4 @@ + o Minor bugfixes (NetBSD): + - Fix usage of minherit() on NetBSD and other platforms that define + MAP_INHERIT_{ZERO,NONE} instead of INHERIT_{ZERO,NONE}. Fixes bug + 30614; bugfix on 0.4.0.2-alpha. Patch from Taylor Campbell. From 5cbd71b977f1c3ae0b9dc0f9e63094941ece015c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 29 May 2019 11:00:09 -0400 Subject: [PATCH 06/12] Make get_proxy_type() connection-specific Previously, we were looking at our global settings to see what kind of proxy we had. But doing this would sometimes give us the wrong results when we had ClientTransportPlugin configured but we weren't using it for a particular connection. In several places in the code, we had added checks to see if we were _really_ using a PT or whether we were using a socks proxy, but we had forgotten to do so in at least once case. Instead, since every time we call this function we are asking about a single connection, it is probably best just to make this function connection-specific. Fixes bug 29670; bugfix on 0.2.6.2-alpha. --- changes/bug29670 | 4 ++++ src/core/mainloop/connection.c | 33 +++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 changes/bug29670 diff --git a/changes/bug29670 b/changes/bug29670 new file mode 100644 index 0000000000..00b0c33327 --- /dev/null +++ b/changes/bug29670 @@ -0,0 +1,4 @@ + o Minor bugfixes (configuration, proxies): + - Fix a bug that prevented us from supporting SOCKS5 proxies that want + authentication along with configued (but unused!) + ClientTransportPlugins. Fixes bug 29670; bugfix on 0.2.6.1-alpha. diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c index 7b8dc7f364..29ef26ca5a 100644 --- a/src/core/mainloop/connection.c +++ b/src/core/mainloop/connection.c @@ -182,7 +182,7 @@ static const char *connection_proxy_state_to_string(int state); static int connection_read_https_proxy_response(connection_t *conn); static void connection_send_socks5_connect(connection_t *conn); static const char *proxy_type_to_string(int proxy_type); -static int get_proxy_type(void); +static int conn_get_proxy_type(const connection_t *conn); const tor_addr_t *conn_get_outbound_address(sa_family_t family, const or_options_t *options, unsigned int conn_type); static void reenable_blocked_connection_init(const or_options_t *options); @@ -2260,18 +2260,27 @@ connection_proxy_state_to_string(int state) return states[state]; } -/** Returns the global proxy type used by tor. Use this function for - * logging or high-level purposes, don't use it to fill the +/** Returns the proxy type used by tor for a single connection, for + * logging or high-level purposes. Don't use it to fill the * proxy_type field of or_connection_t; use the actual proxy * protocol instead.*/ static int -get_proxy_type(void) +conn_get_proxy_type(const connection_t *conn) { const or_options_t *options = get_options(); - if (options->ClientTransportPlugin) - return PROXY_PLUGGABLE; - else if (options->HTTPSProxy) + if (options->ClientTransportPlugin) { + /* If we have plugins configured *and* this addr/port is a known bridge + * with a transport, then we should be PROXY_PLUGGABLE. */ + const transport_t *transport = NULL; + int r; + r = get_transport_by_bridge_addrport(&conn->addr, conn->port, &transport); + if (r == 0 && transport) + return PROXY_PLUGGABLE; + } + + /* In all other cases, we're using a global proxy. */ + if (options->HTTPSProxy) return PROXY_CONNECT; else if (options->Socks4Proxy) return PROXY_SOCKS4; @@ -2358,7 +2367,7 @@ connection_proxy_connect(connection_t *conn, int type) arguments to transmit. If we do, compress all arguments to a single string in 'socks_args_string': */ - if (get_proxy_type() == PROXY_PLUGGABLE) { + if (conn_get_proxy_type(conn) == PROXY_PLUGGABLE) { socks_args_string = pt_get_socks_args_for_proxy_addrport(&conn->addr, conn->port); if (socks_args_string) @@ -2418,7 +2427,7 @@ connection_proxy_connect(connection_t *conn, int type) Socks5ProxyUsername or if we want to pass arguments to our pluggable transport proxy: */ if ((options->Socks5ProxyUsername) || - (get_proxy_type() == PROXY_PLUGGABLE && + (conn_get_proxy_type(conn) == PROXY_PLUGGABLE && (get_socks_args_by_bridge_addrport(&conn->addr, conn->port)))) { /* number of auth methods */ buf[1] = 2; @@ -2611,16 +2620,16 @@ connection_read_proxy_handshake(connection_t *conn) const char *user, *pass; char *socks_args_string = NULL; - if (get_proxy_type() == PROXY_PLUGGABLE) { + if (conn_get_proxy_type(conn) == PROXY_PLUGGABLE) { socks_args_string = pt_get_socks_args_for_proxy_addrport(&conn->addr, conn->port); if (!socks_args_string) { - log_warn(LD_NET, "Could not create SOCKS args string."); + log_warn(LD_NET, "Could not create SOCKS args string for PT."); ret = -1; break; } - log_debug(LD_NET, "SOCKS5 arguments: %s", socks_args_string); + log_debug(LD_NET, "PT SOCKS5 arguments: %s", socks_args_string); tor_assert(strlen(socks_args_string) > 0); tor_assert(strlen(socks_args_string) <= MAX_SOCKS5_AUTH_SIZE_TOTAL); From 70b85358afd0a8d4291489f9e9f5654ab2d53371 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 31 May 2019 08:26:10 -0400 Subject: [PATCH 07/12] Fix a logic error in deciding whether to accept SessionGroup= Fixes bug 22619; bugfix on 0.2.7.2-alpha --- changes/bug22619 | 3 +++ src/app/config/config.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 changes/bug22619 diff --git a/changes/bug22619 b/changes/bug22619 new file mode 100644 index 0000000000..9c71996f5b --- /dev/null +++ b/changes/bug22619 @@ -0,0 +1,3 @@ + o Minor bugfixes (circuit isolation): + - Fix a logic error that prevented the SessionGroup sub-option from + being accepted. Fixes bug 22619; bugfix on 0.2.7.2-alpha. diff --git a/src/app/config/config.c b/src/app/config/config.c index 2a504d3065..3525597591 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -7080,7 +7080,7 @@ parse_port_config(smartlist_t *out, if (!strcasecmpstart(elt, "SessionGroup=")) { int group = (int)tor_parse_long(elt+strlen("SessionGroup="), 10, 0, INT_MAX, &ok, NULL); - if (!ok || !allow_no_stream_options) { + if (!ok || allow_no_stream_options) { log_warn(LD_CONFIG, "Invalid %sPort option '%s'", portname, escaped(elt)); goto err; From 3c3158f1826826d9b4e8841bc67855cca0fc883b Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 31 May 2019 09:03:16 -0400 Subject: [PATCH 08/12] Fix some tests for CL_PORT_NO_STREAM_OPTIONS The comment in the tests was correct: this option _was_ inverted wrt SessionGroup=. --- src/test/test_config.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/test/test_config.c b/src/test/test_config.c index c342d8cca4..0de6b12919 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -4568,16 +4568,14 @@ test_config_parse_port_config__ports__ports_given(void *data) "127.0.0.44", 0, CL_PORT_NO_STREAM_OPTIONS); tt_int_op(ret, OP_EQ, -1); - // TODO: this seems wrong. Shouldn't it be the other way around? - // Potential bug. - // Test failure for a SessionGroup argument with valid value but with stream - // options allowed + // Test failure for a SessionGroup argument with valid value but with no + // stream options allowed config_free_lines(config_port_invalid); config_port_invalid = NULL; SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf)); smartlist_clear(slout); config_port_invalid = mock_config_line("DNSPort", "42 SessionGroup=123"); ret = parse_port_config(slout, config_port_invalid, "DNS", 0, - "127.0.0.44", 0, 0); + "127.0.0.44", 0, CL_PORT_NO_STREAM_OPTIONS); tt_int_op(ret, OP_EQ, -1); // Test failure for more than one SessionGroup argument @@ -4587,7 +4585,7 @@ test_config_parse_port_config__ports__ports_given(void *data) config_port_invalid = mock_config_line("DNSPort", "42 SessionGroup=123 " "SessionGroup=321"); ret = parse_port_config(slout, config_port_invalid, "DNS", 0, - "127.0.0.44", 0, CL_PORT_NO_STREAM_OPTIONS); + "127.0.0.44", 0, 0); tt_int_op(ret, OP_EQ, -1); // Test success with a sessiongroup options @@ -4596,7 +4594,7 @@ test_config_parse_port_config__ports__ports_given(void *data) smartlist_clear(slout); config_port_valid = mock_config_line("DNSPort", "42 SessionGroup=1111122"); ret = parse_port_config(slout, config_port_valid, "DNS", 0, - "127.0.0.44", 0, CL_PORT_NO_STREAM_OPTIONS); + "127.0.0.44", 0, 0); tt_int_op(ret, OP_EQ, 0); tt_int_op(smartlist_len(slout), OP_EQ, 1); port_cfg = (port_cfg_t *)smartlist_get(slout, 0); From 5b3c8865842f3b12d3ea35db19e8feb135bb46dc Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 31 May 2019 11:46:58 -0400 Subject: [PATCH 09/12] Consider dir info to have changed when the bridges change Otherwise, we won't realize that we haven't got enough bridge information to build circuits. Part of a fix for ticket 29875. --- src/app/config/config.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/config/config.c b/src/app/config/config.c index 2a504d3065..7f6657db3c 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -2412,7 +2412,8 @@ options_act(const or_options_t *old_options) if (!bool_eq(directory_fetches_dir_info_early(options), directory_fetches_dir_info_early(old_options)) || !bool_eq(directory_fetches_dir_info_later(options), - directory_fetches_dir_info_later(old_options))) { + directory_fetches_dir_info_later(old_options)) || + !config_lines_eq(old_options->Bridges, options->Bridges)) { /* Make sure update_router_have_minimum_dir_info() gets called. */ router_dir_info_changed(); /* We might need to download a new consensus status later or sooner than From 8015979eeba2c8b10fb058318628debf228fb023 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 31 May 2019 12:19:29 -0400 Subject: [PATCH 10/12] num_bridges_usable(): only count configured bridges. When this function was implemented, it counted all the entry guards in the bridge set. But this included previously configured bridges, as well as currently configured ones! Instead, only count the _filtered_ bridges (ones that are configured and possibly reachable) as maybe usable. Fixes bug 29875; bugfix on 0.3.0.1-alpha. --- src/feature/client/entrynodes.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/feature/client/entrynodes.c b/src/feature/client/entrynodes.c index e543289ce0..15ec830594 100644 --- a/src/feature/client/entrynodes.c +++ b/src/feature/client/entrynodes.c @@ -3300,6 +3300,9 @@ num_bridges_usable,(int use_maybe_reachable)) } SMARTLIST_FOREACH_BEGIN(gs->sampled_entry_guards, entry_guard_t *, guard) { + /* Not a bridge, or not one we are configured to be able to use. */ + if (! guard->is_filtered_guard) + continue; /* Definitely not usable */ if (guard->is_reachable == GUARD_REACHABLE_NO) continue; From c09e7a4e715d8266517896cfbc8fc80f19feba85 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 31 May 2019 12:39:52 -0400 Subject: [PATCH 11/12] changes file for bug 29875. --- changes/bug29875 | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 changes/bug29875 diff --git a/changes/bug29875 b/changes/bug29875 new file mode 100644 index 0000000000..58a1c871cd --- /dev/null +++ b/changes/bug29875 @@ -0,0 +1,11 @@ + o Major bugfixes (bridges): + - Do not count previously configured working bridges towards our total of + working bridges. Previously, when Tor's list of bridges changed, it + would think that the old bridges were still usable, and delay fetching + router descriptors for the new ones. Fixes part of bug 29875; bugfix + on 0.3.0.1-alpha. + - Consider our directory information to have changed when our list of + bridges changes. Previously, Tor would not re-compute the status of its + directory information when bridges changed, and therefore would not + realize that it was no longer able to build circuits. Fixes part of bug + 29875. From a6399da598101d8046cbf7ab2d80051fd8820e2f Mon Sep 17 00:00:00 2001 From: Mike Perry Date: Wed, 5 Jun 2019 11:50:44 -0700 Subject: [PATCH 12/12] Bug 29034: Cleanup hs circuitmap when purpose changes. Leave the other rend and hs_ident data around until circuit free, since code may still try to inspect it after marking the circuit for close. The circuitmap is the important thing to clean up, since repurposed intropoints must be removed from this map to ensure validity. --- changes/bug29034 | 5 +++++ src/core/or/circuituse.c | 6 ++++++ 2 files changed, 11 insertions(+) create mode 100644 changes/bug29034 diff --git a/changes/bug29034 b/changes/bug29034 new file mode 100644 index 0000000000..e7aa9af00b --- /dev/null +++ b/changes/bug29034 @@ -0,0 +1,5 @@ + o Major bugfixes (Onion service reachability): + - Properly clean up the introduction point map when circuits change purpose + from onion service circuits to pathbias, measurement, or other circuit types. + This should fix some service-side instances of introduction point failure. + Fixes bug 29034; bugfix on 0.3.2.1-alpha. diff --git a/src/core/or/circuituse.c b/src/core/or/circuituse.c index 02bfa15fb3..000a7c36da 100644 --- a/src/core/or/circuituse.c +++ b/src/core/or/circuituse.c @@ -3066,6 +3066,12 @@ circuit_change_purpose(circuit_t *circ, uint8_t new_purpose) circ->purpose, circuit_purpose_to_string(new_purpose), new_purpose); + + /* Take specific actions if we are repurposing a hidden service circuit. */ + if (circuit_purpose_is_hidden_service(circ->purpose) && + !circuit_purpose_is_hidden_service(new_purpose)) { + hs_circ_cleanup(circ); + } } old_purpose = circ->purpose;