summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changes/bug62516
-rw-r--r--changes/bug640416
-rw-r--r--changes/bug64724
-rw-r--r--changes/bug66907
-rw-r--r--changes/bug67106
-rw-r--r--changes/disable_pathbias_messages3
-rw-r--r--doc/tor.1.txt6
-rw-r--r--src/or/circuitbuild.c29
-rw-r--r--src/or/config.c2
-rw-r--r--src/or/dirvote.c48
-rw-r--r--src/or/dns.c16
-rw-r--r--src/or/microdesc.c7
-rw-r--r--src/or/or.h4
-rw-r--r--src/or/policies.c6
-rw-r--r--src/or/routerparse.c5
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);
}
}