diff options
-rw-r--r-- | changes/bug6251 | 6 | ||||
-rw-r--r-- | changes/bug6404 | 16 | ||||
-rw-r--r-- | changes/bug6472 | 4 | ||||
-rw-r--r-- | changes/bug6690 | 7 | ||||
-rw-r--r-- | changes/bug6710 | 6 | ||||
-rw-r--r-- | changes/disable_pathbias_messages | 3 | ||||
-rw-r--r-- | doc/tor.1.txt | 6 | ||||
-rw-r--r-- | src/or/circuitbuild.c | 29 | ||||
-rw-r--r-- | src/or/config.c | 2 | ||||
-rw-r--r-- | src/or/dirvote.c | 48 | ||||
-rw-r--r-- | src/or/dns.c | 16 | ||||
-rw-r--r-- | src/or/microdesc.c | 7 | ||||
-rw-r--r-- | src/or/or.h | 4 | ||||
-rw-r--r-- | src/or/policies.c | 6 | ||||
-rw-r--r-- | src/or/routerparse.c | 5 |
15 files changed, 124 insertions, 41 deletions
diff --git a/changes/bug6251 b/changes/bug6251 new file mode 100644 index 0000000000..c782a93e49 --- /dev/null +++ b/changes/bug6251 @@ -0,0 +1,6 @@ + o Minor bugfixes: + - Downgrade "set buildtimeout to low value" messages to INFO + severity; they were never an actual problem, there was never + anything reasonable to do about them, and they tended to spam + logs from time to time. Fix for bug 6251; bugfix on + 0.2.2.2-alpha.
\ No newline at end of file diff --git a/changes/bug6404 b/changes/bug6404 new file mode 100644 index 0000000000..948f00b92e --- /dev/null +++ b/changes/bug6404 @@ -0,0 +1,16 @@ + o Minor bugfixes: + + - Remove the maximum length of microdescriptor we are willing to + generate. Occasionally this is needed for routers + with complex policies or family declarations. Partial fix for + bug 6404; fix on 0.2.2.6-alpha. + + - Authorities no longer include any router in their + microdescriptor consensuses for which they couldn't generate or + agree on a microdescriptor. Partial fix for bug 6404; fix on + 0.2.2.6-alpha. + + - Move log message when unable to find a microdesc in a + routerstatus entry to parse time. Previously we'd spam this + warning every time we tried to figure out which microdescriptors + to download. Partial fix for bug 6404; fix on 0.2.3.18-rc. diff --git a/changes/bug6472 b/changes/bug6472 new file mode 100644 index 0000000000..dcd42ebe68 --- /dev/null +++ b/changes/bug6472 @@ -0,0 +1,4 @@ + o Minor bugfixes: + - Avoid a pair of double-free and use-after-mark bugs that can + occur with certain timings in canceled and re-received DNS + requests. Fix for bug 6472; bugfix on 0.0.7rc1. diff --git a/changes/bug6690 b/changes/bug6690 new file mode 100644 index 0000000000..99d42976ed --- /dev/null +++ b/changes/bug6690 @@ -0,0 +1,7 @@ + o Major bugfixes (security): + - Do not crash when comparing an address with port value 0 to an + address policy. This bug could have been used to cause a remote + assertion failure by or against directory authorities, or to + allow some applications to crash clients. Fixes bug 6690; bugfix + on 0.2.1.10-alpha. + diff --git a/changes/bug6710 b/changes/bug6710 new file mode 100644 index 0000000000..2c89346114 --- /dev/null +++ b/changes/bug6710 @@ -0,0 +1,6 @@ + o Major bugfixes (security): + - Reject any attempt to extend to an internal address. Without + this fix, a router could be used to probe addresses on an + internal network to see whether they were accepting + connections. Fix for bug 6710; bugfix on 0.0.8pre1. + diff --git a/changes/disable_pathbias_messages b/changes/disable_pathbias_messages new file mode 100644 index 0000000000..3bc996347b --- /dev/null +++ b/changes/disable_pathbias_messages @@ -0,0 +1,3 @@ + o Disabeled features + - Downgrade path-bias warning messages to INFO. We'll try to get them + working better in 0.2.4. Fixes bug 6475; bugfix on 0.2.3.17-beta. diff --git a/doc/tor.1.txt b/doc/tor.1.txt index 971a0efe4b..62259b7268 100644 --- a/doc/tor.1.txt +++ b/doc/tor.1.txt @@ -1470,6 +1470,11 @@ is non-zero): its extra-info documents that it uploads to the directory authorities. (Default: 1) +**ExtendAllowPrivateAddresses** **0**|**1**:: + When this option is enabled, Tor routers allow EXTEND request to + localhost, RFC1918 addresses, and so on. This can create security issues; + you should probably leave it off. (Default: 0) + DIRECTORY SERVER OPTIONS ------------------------ @@ -1795,6 +1800,7 @@ The following options are used for running a testing Tor network. ClientRejectInternalAddresses 0 CountPrivateBandwidth 1 ExitPolicyRejectPrivate 0 + ExtendAllowPrivateAddresses 1 V3AuthVotingInterval 5 minutes V3AuthVoteDelay 20 seconds V3AuthDistDelay 20 seconds diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 39a223b2f4..e5576018a6 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -1627,7 +1627,7 @@ circuit_build_times_set_timeout(circuit_build_times_t *cbt) return; if (cbt->timeout_ms < circuit_build_times_min_timeout()) { - log_warn(LD_CIRC, "Set buildtimeout to low value %fms. Setting to %dms", + log_info(LD_CIRC, "Set buildtimeout to low value %fms. Setting to %dms", cbt->timeout_ms, circuit_build_times_min_timeout()); cbt->timeout_ms = circuit_build_times_min_timeout(); if (cbt->close_ms < cbt->timeout_ms) { @@ -2432,6 +2432,13 @@ circuit_extend(cell_t *cell, circuit_t *circ) return -1; } + if (tor_addr_is_internal(&n_addr, 0) && + !get_options()->ExtendAllowPrivateAddresses) { + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Client asked me to extend to a private address"); + return -1; + } + /* Check if they asked us for 0000..0000. We support using * an empty fingerprint for the first hop (e.g. for a bridge relay), * but we don't want to let people send us extend cells for empty @@ -2649,7 +2656,7 @@ pathbias_count_first_hop(origin_circuit_t *circ) if (circ->has_opened && circ->path_state != PATH_STATE_DID_FIRST_HOP) { if ((rate_msg = rate_limit_log(&first_hop_notice_limit, approx_time()))) { - log_notice(LD_BUG, + log_info(LD_BUG, "Opened circuit is in strange path state %s. " "Circuit is a %s currently %s. %s", pathbias_state_to_string(circ->path_state), @@ -2676,7 +2683,7 @@ pathbias_count_first_hop(origin_circuit_t *circ) } else { if ((rate_msg = rate_limit_log(&first_hop_notice_limit, approx_time()))) { - log_notice(LD_BUG, + log_info(LD_BUG, "Unopened circuit has strange path state %s. " "Circuit is a %s currently %s. %s", pathbias_state_to_string(circ->path_state), @@ -2688,7 +2695,7 @@ pathbias_count_first_hop(origin_circuit_t *circ) } else { if ((rate_msg = rate_limit_log(&first_hop_notice_limit, approx_time()))) { - log_notice(LD_BUG, + log_info(LD_BUG, "Unopened circuit has no known guard. " "Circuit is a %s currently %s. %s", circuit_purpose_to_string(circ->_base.purpose), @@ -2702,7 +2709,7 @@ pathbias_count_first_hop(origin_circuit_t *circ) if (circ->path_state == PATH_STATE_NEW_CIRC) { if ((rate_msg = rate_limit_log(&first_hop_notice_limit, approx_time()))) { - log_notice(LD_BUG, + log_info(LD_BUG, "A %s circuit is in cpath state %d (opened: %d). " "Circuit is a %s currently %s. %s", pathbias_state_to_string(circ->path_state), @@ -2754,7 +2761,7 @@ pathbias_count_success(origin_circuit_t *circ) } else { if ((rate_msg = rate_limit_log(&success_notice_limit, approx_time()))) { - log_notice(LD_BUG, + log_info(LD_BUG, "Succeeded circuit is in strange path state %s. " "Circuit is a %s currently %s. %s", pathbias_state_to_string(circ->path_state), @@ -2765,7 +2772,7 @@ pathbias_count_success(origin_circuit_t *circ) } if (guard->first_hops < guard->circuit_successes) { - log_warn(LD_BUG, "Unexpectedly high circuit_successes (%u/%u) " + log_info(LD_BUG, "Unexpectedly high circuit_successes (%u/%u) " "for guard %s=%s", guard->circuit_successes, guard->first_hops, guard->nickname, hex_str(guard->identity, DIGEST_LEN)); @@ -2773,7 +2780,7 @@ pathbias_count_success(origin_circuit_t *circ) } else { if ((rate_msg = rate_limit_log(&success_notice_limit, approx_time()))) { - log_notice(LD_BUG, + log_info(LD_BUG, "Completed circuit has no known guard. " "Circuit is a %s currently %s. %s", circuit_purpose_to_string(circ->_base.purpose), @@ -2785,7 +2792,7 @@ pathbias_count_success(origin_circuit_t *circ) if (circ->path_state != PATH_STATE_SUCCEEDED) { if ((rate_msg = rate_limit_log(&success_notice_limit, approx_time()))) { - log_notice(LD_BUG, + log_info(LD_BUG, "Opened circuit is in strange path state %s. " "Circuit is a %s currently %s. %s", pathbias_state_to_string(circ->path_state), @@ -2815,7 +2822,7 @@ entry_guard_inc_first_hop_count(entry_guard_t *guard) if (guard->circuit_successes/((double)guard->first_hops) < pathbias_get_disable_rate(options)) { - log_warn(LD_PROTOCOL, + log_info(LD_PROTOCOL, "Extremely low circuit success rate %u/%u for guard %s=%s. " "This might indicate an attack, or a bug.", guard->circuit_successes, guard->first_hops, guard->nickname, @@ -2828,7 +2835,7 @@ entry_guard_inc_first_hop_count(entry_guard_t *guard) < pathbias_get_notice_rate(options) && !guard->path_bias_notice) { guard->path_bias_notice = 1; - log_notice(LD_PROTOCOL, + log_info(LD_PROTOCOL, "Low circuit success rate %u/%u for guard %s=%s.", guard->circuit_successes, guard->first_hops, guard->nickname, hex_str(guard->identity, DIGEST_LEN)); diff --git a/src/or/config.c b/src/or/config.c index 3970808fb3..d5e80cc832 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -276,6 +276,7 @@ static config_var_t _option_vars[] = { V(ExitPolicy, LINELIST, NULL), V(ExitPolicyRejectPrivate, BOOL, "1"), V(ExitPortStatistics, BOOL, "0"), + V(ExtendAllowPrivateAddresses, BOOL, "0"), V(ExtraInfoStatistics, BOOL, "1"), #if defined (WINCE) @@ -473,6 +474,7 @@ static const config_var_t testing_tor_network_defaults[] = { V(ClientRejectInternalAddresses, BOOL, "0"), V(CountPrivateBandwidth, BOOL, "1"), V(ExitPolicyRejectPrivate, BOOL, "0"), + V(ExtendAllowPrivateAddresses, BOOL, "1"), V(V3AuthVotingInterval, INTERVAL, "5 minutes"), V(V3AuthVoteDelay, INTERVAL, "20 seconds"), V(V3AuthDistDelay, INTERVAL, "20 seconds"), diff --git a/src/or/dirvote.c b/src/or/dirvote.c index bc7797355c..b3de90b5c0 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -54,7 +54,7 @@ static int dirvote_publish_consensus(void); static char *make_consensus_method_list(int low, int high, const char *sep); /** The highest consensus method that we currently support. */ -#define MAX_SUPPORTED_CONSENSUS_METHOD 12 +#define MAX_SUPPORTED_CONSENSUS_METHOD 13 /** Lowest consensus method that contains a 'directory-footer' marker */ #define MIN_METHOD_FOR_FOOTER 9 @@ -72,6 +72,10 @@ static char *make_consensus_method_list(int low, int high, const char *sep); * for a param. */ #define MIN_METHOD_FOR_MAJORITY_PARAMS 12 +/** Lowest consensus method where microdesc consensuses omit any entry + * with no microdesc. */ +#define MIN_METHOD_FOR_MANDATORY_MICRODESC 13 + /* ===== * Voting * =====*/ @@ -1936,6 +1940,13 @@ networkstatus_compute_consensus(smartlist_t *votes, } } + if (flavor == FLAV_MICRODESC && + consensus_method >= MIN_METHOD_FOR_MANDATORY_MICRODESC && + tor_digest256_is_zero(microdesc_digest)) { + /* With no microdescriptor digest, we omit the entry entirely. */ + continue; + } + { char buf[4096]; /* Okay!! Now we can write the descriptor... */ @@ -3503,9 +3514,9 @@ dirvote_create_microdescriptor(const routerinfo_t *ri) { microdesc_t *result = NULL; char *key = NULL, *summary = NULL, *family = NULL; - char buf[1024]; size_t keylen; - char *out = buf, *end = buf+sizeof(buf); + smartlist_t *chunks = smartlist_new(); + char *output = NULL; if (crypto_pk_write_public_key_to_string(ri->onion_pkey, &key, &keylen)<0) goto done; @@ -3513,23 +3524,19 @@ dirvote_create_microdescriptor(const routerinfo_t *ri) if (ri->declared_family) family = smartlist_join_strings(ri->declared_family, " ", 0, NULL); - if (tor_snprintf(out, end-out, "onion-key\n%s", key)<0) - goto done; - out += strlen(out); - if (family) { - if (tor_snprintf(out, end-out, "family %s\n", family)<0) - goto done; - out += strlen(out); - } - if (summary && strcmp(summary, "reject 1-65535")) { - if (tor_snprintf(out, end-out, "p %s\n", summary)<0) - goto done; - out += strlen(out); - } - *out = '\0'; /* Make sure it's nul-terminated. This should be a no-op */ + smartlist_add_asprintf(chunks, "onion-key\n%s", key); + + if (family) + smartlist_add_asprintf(chunks, "family %s\n", family); + + if (summary && strcmp(summary, "reject 1-65535")) + smartlist_add_asprintf(chunks, "p %s\n", summary); + + output = smartlist_join_strings(chunks, "", 0, NULL); { - smartlist_t *lst = microdescs_parse_from_string(buf, out, 0, 1); + smartlist_t *lst = microdescs_parse_from_string(output, + output+strlen(output), 0, 1); 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)); @@ -3541,9 +3548,14 @@ dirvote_create_microdescriptor(const routerinfo_t *ri) } done: + tor_free(output); tor_free(key); tor_free(summary); tor_free(family); + if (chunks) { + SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp)); + smartlist_free(chunks); + } return result; } diff --git a/src/or/dns.c b/src/or/dns.c index 3e88fad68c..78893bfbed 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -450,16 +450,17 @@ purge_expired_resolves(time_t now) if (resolve->pending_connections) { log_debug(LD_EXIT, "Closing pending connections on timed-out DNS resolve!"); - tor_fragile_assert(); while (resolve->pending_connections) { pend = resolve->pending_connections; resolve->pending_connections = pend->next; /* Connections should only be pending if they have no socket. */ tor_assert(!SOCKET_OK(pend->conn->_base.s)); pendconn = pend->conn; - connection_edge_end(pendconn, END_STREAM_REASON_TIMEOUT); - circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn); - connection_free(TO_CONN(pendconn)); + if (!pendconn->_base.marked_for_close) { + connection_edge_end(pendconn, END_STREAM_REASON_TIMEOUT); + circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn); + connection_free(TO_CONN(pendconn)); + } tor_free(pend); } } @@ -1091,6 +1092,13 @@ dns_found_answer(const char *address, uint8_t is_reverse, uint32_t addr, pendconn = pend->conn; /* don't pass complex things to the connection_mark_for_close macro */ assert_connection_ok(TO_CONN(pendconn),time(NULL)); + if (pendconn->_base.marked_for_close) { + /* prevent double-remove. */ + pendconn->_base.state = EXIT_CONN_STATE_RESOLVEFAILED; + resolve->pending_connections = pend->next; + tor_free(pend); + continue; + } tor_addr_from_ipv4h(&pendconn->_base.addr, addr); pendconn->address_ttl = ttl; diff --git a/src/or/microdesc.c b/src/or/microdesc.c index 9395a9a051..c1ac1c3758 100644 --- a/src/or/microdesc.c +++ b/src/or/microdesc.c @@ -643,13 +643,8 @@ microdesc_list_missing_digest256(networkstatus_t *ns, microdesc_cache_t *cache, continue; if (skip && digestmap_get(skip, rs->descriptor_digest)) continue; - if (tor_mem_is_zero(rs->descriptor_digest, DIGEST256_LEN)) { - log_info(LD_BUG, "Found an entry in networkstatus with no " - "microdescriptor digest. (Router %s=%s at %s:%d.)", - rs->nickname, hex_str(rs->identity_digest, DIGEST_LEN), - fmt_addr32(rs->addr), rs->or_port); + if (tor_mem_is_zero(rs->descriptor_digest, DIGEST256_LEN)) continue; - } /* XXXX Also skip if we're a noncache and wouldn't use this router. * XXXX NM Microdesc */ diff --git a/src/or/or.h b/src/or/or.h index 908daa61c0..9074083a04 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3029,8 +3029,10 @@ typedef struct { config_line_t *RecommendedVersions; config_line_t *RecommendedClientVersions; config_line_t *RecommendedServerVersions; - /** Whether dirservers refuse router descriptors with private IPs. */ + /** Whether dirservers allow router descriptors with private IPs. */ int DirAllowPrivateAddresses; + /** Whether routers accept EXTEND cells to routers with private IPs. */ + int ExtendAllowPrivateAddresses; char *User; /**< Name of user to run Tor as. */ char *Group; /**< Name of group to run Tor as. */ config_line_t *ORPort_lines; /**< Ports to listen on for OR connections. */ diff --git a/src/or/policies.c b/src/or/policies.c index 3018803bc4..6e984211ba 100644 --- a/src/or/policies.c +++ b/src/or/policies.c @@ -712,7 +712,11 @@ compare_tor_addr_to_addr_policy(const tor_addr_t *addr, uint16_t port, /* no policy? accept all. */ return ADDR_POLICY_ACCEPTED; } else if (addr == NULL || tor_addr_is_null(addr)) { - tor_assert(port != 0); + if (port == 0) { + log_info(LD_BUG, "Rejecting null address with 0 port (family %d)", + addr ? tor_addr_family(addr) : -1); + return ADDR_POLICY_REJECTED; + } return compare_unknown_tor_addr_to_addr_policy(port, policy); } else if (port == 0) { return compare_known_tor_addr_to_addr_policy_noport(addr, policy); diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 3875198a2c..60a2eae75f 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -2201,6 +2201,11 @@ routerstatus_parse_entry_from_string(memarea_t *area, escaped(tok->args[0])); goto err; } + } else { + log_info(LD_BUG, "Found an entry in networkstatus with no " + "microdescriptor digest. (Router %s=%s at %s:%d.)", + rs->nickname, hex_str(rs->identity_digest, DIGEST_LEN), + fmt_addr32(rs->addr), rs->or_port); } } |