diff --git a/changes/bug13988 b/changes/bug13988
new file mode 100644
index 000000000..e816335a3
--- /dev/null
+++ b/changes/bug13988
@@ -0,0 +1,3 @@
+ o Minor bugfixes (statistics):
+ - Increase period over which bandwidth observations are aggregated
+ from 15 minutes to 4 hours. Fixes bug 13988; bugfix on 0.0.8pre1.
diff --git a/changes/bug14013 b/changes/bug14013
new file mode 100644
index 000000000..640cf859f
--- /dev/null
+++ b/changes/bug14013
@@ -0,0 +1,6 @@
+ o Major bugfixes:
+ - When reading a hexadecimal, base-32, or base-64 encoded value
+ from a string, always overwrite the complete output buffer. This
+ prevents some bugs where we would look at (but fortunately, not
+ reveal) uninitialized memory on the stack. Fixes bug 14013;
+ bugfix on all versions of Tor.
diff --git a/changes/bug14125 b/changes/bug14125
new file mode 100644
index 000000000..fe6821a33
--- /dev/null
+++ b/changes/bug14125
@@ -0,0 +1,5 @@
+ o Minor bugfixes (dirauth):
+ - Enlarge the buffer to read bw-auth generated files to avoid an
+ issue when parsing the file in dirserv_read_measured_bandwidths().
+ Bugfix on 0.2.2.1-alpha, fixes #14125.
+
diff --git a/changes/bug14129 b/changes/bug14129
new file mode 100644
index 000000000..6153cd84f
--- /dev/null
+++ b/changes/bug14129
@@ -0,0 +1,7 @@
+ o Major bugfixes (exit node stability):
+
+ - Fix an assertion failure that could occur under high DNS load. Fixes
+ bug 14129; bugfix on Tor 0.0.7rc1. Found by "jowr"; diagnosed and fixed
+ by "cypherpunks".
+
+
diff --git a/changes/bug14142-parse-virtual-addr b/changes/bug14142-parse-virtual-addr
new file mode 100644
index 000000000..f78b7c7d8
--- /dev/null
+++ b/changes/bug14142-parse-virtual-addr
@@ -0,0 +1,7 @@
+ o Minor bugfixes (client):
+ - Check for a missing option value in parse_virtual_addr_network
+ before asserting on the NULL in tor_addr_parse_mask_ports.
+ This avoids crashing on torrc lines like
+ Vi[rtualAddrNetworkIPv[4|6]] when no value follows the option.
+ Bugfix on 0.2.3 (de4cc126cbb5 on 24 November 2012), fixes #14142.
+ Patch by "teor".
diff --git a/changes/bug14195 b/changes/bug14195
new file mode 100644
index 000000000..d2b82f31b
--- /dev/null
+++ b/changes/bug14195
@@ -0,0 +1,3 @@
+ o Minor bugfixes (client):
+ - Fix a memory leak when using AutomapHostsOnResolve.
+ Fixes bug 14195; bugfix on 0.1.0.1-rc.
diff --git a/changes/bug14220 b/changes/bug14220
new file mode 100644
index 000000000..51cfa502b
--- /dev/null
+++ b/changes/bug14220
@@ -0,0 +1,4 @@
+ o Minor bugfixes (compilation):
+ - Build without warnings with the stock OpenSSL srtp.h header,
+ which has a duplicate declaration of SSL_get_selected_srtp_profile().
+ Fixes bug 14220; this is OpenSSL's bug, not ours.
diff --git a/changes/bug14261 b/changes/bug14261
new file mode 100644
index 000000000..1260ccba1
--- /dev/null
+++ b/changes/bug14261
@@ -0,0 +1,5 @@
+ O Minor bugfixes (directory authority):
+ - Allow directory authorities to fetch more data from one
+ another if they find themselves missing lots of votes.
+ Previously, they had been bumping against the 10 MB queued
+ data limit. Fixes bug 14261. Bugfix on 0.1.2.5-alpha.
diff --git a/changes/bug15083 b/changes/bug15083
new file mode 100644
index 000000000..5cc79b5ba
--- /dev/null
+++ b/changes/bug15083
@@ -0,0 +1,10 @@
+ o Major bugfixes (relay, stability, possible security):
+ - Fix a bug that could lead to a relay crashing with an assertion
+ failure if a buffer of exactly the wrong layout was passed
+ to buf_pullup() at exactly the wrong time. Fixes bug 15083;
+ bugfix on 0.2.0.10-alpha. Patch from 'cypherpunks'.
+
+ - Do not assert if the 'data' pointer on a buffer is advanced to the very
+ end of the buffer; log a BUG message instead. Only assert if it is
+ past that point. Fixes bug 15083; bugfix on 0.2.0.10-alpha.
+
diff --git a/changes/bug15088 b/changes/bug15088
new file mode 100644
index 000000000..95878bdb3
--- /dev/null
+++ b/changes/bug15088
@@ -0,0 +1,4 @@
+ o Minor bugfixes (Linux seccomp2 sandbox):
+ - Upon receiving sighup, do not crash during attempts to call
+ wait4. Fixes bug 15088; bugfix on 0.2.5.1-alpha. Patch from
+ "sanic".
diff --git a/changes/geoip-january2015 b/changes/geoip-january2015
new file mode 100644
index 000000000..67324f27f
--- /dev/null
+++ b/changes/geoip-january2015
@@ -0,0 +1,3 @@
+ o Minor features:
+ - Update geoip to the January 7 2015 Maxmind GeoLite2 Country database.
+
diff --git a/changes/geoip6-january2015 b/changes/geoip6-january2015
new file mode 100644
index 000000000..b86fe2be5
--- /dev/null
+++ b/changes/geoip6-january2015
@@ -0,0 +1,2 @@
+ o Minor features:
+ - Update geoip6 to the January 7 2015 Maxmind GeoLite2 Country database.
diff --git a/changes/ticket14128 b/changes/ticket14128
new file mode 100644
index 000000000..38b25fa7d
--- /dev/null
+++ b/changes/ticket14128
@@ -0,0 +1,5 @@
+ o Minor features (controller):
+ - New "GETINFO bw-event-cache" to get information about recent bandwidth
+ events. Closes ticket 14128. Useful for controllers to get recent
+ bandwidth history after the fix for 13988.
+
diff --git a/changes/ticket14487 b/changes/ticket14487
new file mode 100644
index 000000000..577337ff2
--- /dev/null
+++ b/changes/ticket14487
@@ -0,0 +1,3 @@
+ o Directory authority IP change:
+ - The directory authority Faravahar has a new IP address. Closes
+ ticket 14487.
diff --git a/src/common/crypto.c b/src/common/crypto.c
index a247a87d4..f4e86683d 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -2756,6 +2756,8 @@ base64_decode(char *dest, size_t destlen, const char *src, size_t srclen)
if (destlen > SIZE_T_CEILING)
return -1;
+ memset(dest, 0, destlen);
+
EVP_DecodeInit(&ctx);
EVP_DecodeUpdate(&ctx, (unsigned char*)dest, &len,
(unsigned char*)src, srclen);
@@ -2777,6 +2779,8 @@ base64_decode(char *dest, size_t destlen, const char *src, size_t srclen)
if (destlen > SIZE_T_CEILING)
return -1;
+ memset(dest, 0, destlen);
+
/* Iterate over all the bytes in src. Each one will add 0 or 6 bits to the
* value we're decoding. Accumulate bits in n, and whenever we have
* 24 bits, batch them into 3 bytes and flush those bytes to dest.
@@ -2956,6 +2960,8 @@ base32_decode(char *dest, size_t destlen, const char *src, size_t srclen)
tor_assert((nbits/8) <= destlen); /* We need enough space. */
tor_assert(destlen < SIZE_T_CEILING);
+ memset(dest, 0, destlen);
+
/* Convert base32 encoded chars to the 5-bit values that they represent. */
tmp = tor_malloc_zero(srclen);
for (j = 0; j < srclen; ++j) {
diff --git a/src/common/sandbox.c b/src/common/sandbox.c
index dbbaa59d7..e43b64b91 100644
--- a/src/common/sandbox.c
+++ b/src/common/sandbox.c
@@ -164,6 +164,7 @@ static int filter_nopar_gen[] = {
#endif
SCMP_SYS(stat),
SCMP_SYS(uname),
+ SCMP_SYS(wait4),
SCMP_SYS(write),
SCMP_SYS(writev),
SCMP_SYS(exit_group),
diff --git a/src/common/tortls.c b/src/common/tortls.c
index 999d97131..d637a8e4d 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -33,6 +33,20 @@
#include
#endif
#endif
+
+#ifdef __GNUC__
+#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+#endif
+
+#if __GNUC__ && GCC_VERSION >= 402
+#if GCC_VERSION >= 406
+#pragma GCC diagnostic push
+#endif
+/* Some versions of OpenSSL declare SSL_get_selected_srtp_profile twice in
+ * srtp.h. Suppress the GCC warning so we can build with -Wredundant-decl. */
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
+
#include
#include
#include
@@ -41,6 +55,14 @@
#include
#include
+#if __GNUC__ && GCC_VERSION >= 402
+#if GCC_VERSION >= 406
+#pragma GCC diagnostic pop
+#else
+#pragma GCC diagnostic warning "-Wredundant-decls"
+#endif
+#endif
+
#ifdef USE_BUFFEREVENTS
#include
#include
diff --git a/src/common/util.c b/src/common/util.c
index 2d7893b38..04cc6b12c 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -1129,6 +1129,9 @@ base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
return -1;
if (destlen < srclen/2 || destlen > SIZE_T_CEILING)
return -1;
+
+ memset(dest, 0, destlen);
+
end = src+srclen;
while (srcnew_address)) {
tor_free(new_address);
tor_assert(!vent_needs_to_be_added);
- return tor_strdup(*addrp);
+ return *addrp;
} else {
log_warn(LD_BUG,
"Internal confusion: I thought that '%s' was mapped to by "
diff --git a/src/or/buffers.c b/src/or/buffers.c
index 033f86288..ae73c7070 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -447,7 +447,7 @@ buf_pullup(buf_t *buf, size_t bytes, int nulterminate)
size_t n = bytes - dest->datalen;
src = dest->next;
tor_assert(src);
- if (n > src->datalen) {
+ if (n >= src->datalen) {
memcpy(CHUNK_WRITE_PTR(dest), src->data, src->datalen);
dest->datalen += src->datalen;
dest->next = src->next;
@@ -2624,7 +2624,14 @@ assert_buf_ok(buf_t *buf)
total += ch->datalen;
tor_assert(ch->datalen <= ch->memlen);
tor_assert(ch->data >= &ch->mem[0]);
- tor_assert(ch->data < &ch->mem[0]+ch->memlen);
+ tor_assert(ch->data <= &ch->mem[0]+ch->memlen);
+ if (ch->data == &ch->mem[0]+ch->memlen) {
+ static int warned = 0;
+ if (! warned) {
+ log_warn(LD_BUG, "Invariant violation in buf.c related to #15083");
+ warned = 1;
+ }
+ }
tor_assert(ch->data+ch->datalen <= &ch->mem[0] + ch->memlen);
if (!ch->next)
tor_assert(ch == buf->tail);
diff --git a/src/or/config.c b/src/or/config.c
index 892108278..2a7237d59 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -871,7 +871,7 @@ add_default_trusted_dir_authorities(dirinfo_type_t type)
"171.25.193.9:443 BD6A 8292 55CB 08E6 6FBE 7D37 4836 3586 E46B 3810",
"Faravahar orport=443 "
"v3ident=EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97 "
- "154.35.32.5:80 CF6D 0AAF B385 BE71 B8E1 11FC 5CFF 4B47 9237 33BC",
+ "154.35.175.225:80 CF6D 0AAF B385 BE71 B8E1 11FC 5CFF 4B47 9237 33BC",
"longclaw orport=443 "
"v3ident=23D15D965BC35114467363C165C4F724B64B4F66 "
"199.254.238.52:80 74A9 1064 6BCE EFBC D2E8 74FC 1DC9 9743 0F96 8145",
diff --git a/src/or/control.c b/src/or/control.c
index 9378f38f4..2ff1cc844 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1424,6 +1424,8 @@ getinfo_helper_misc(control_connection_t *conn, const char *question,
(void) conn;
if (!strcmp(question, "version")) {
*answer = tor_strdup(get_version());
+ } else if (!strcmp(question, "bw-event-cache")) {
+ *answer = get_bw_samples();
} else if (!strcmp(question, "config-file")) {
*answer = tor_strdup(get_torrc_fname(0));
} else if (!strcmp(question, "config-defaults-file")) {
@@ -2099,6 +2101,7 @@ typedef struct getinfo_item_t {
* to answer them. */
static const getinfo_item_t getinfo_items[] = {
ITEM("version", misc, "The current version of Tor."),
+ ITEM("bw-event-cache", misc, "Cached BW events for a short interval."),
ITEM("config-file", misc, "Current location of the \"torrc\" file."),
ITEM("config-defaults-file", misc, "Current location of the defaults file."),
ITEM("config-text", misc,
@@ -4133,11 +4136,29 @@ control_event_tb_empty(const char *bucket, uint32_t read_empty_time,
return 0;
}
+/* about 5 minutes worth. */
+#define N_BW_EVENTS_TO_CACHE 300
+/* Index into cached_bw_events to next write. */
+static int next_measurement_idx = 0;
+/* number of entries set in n_measurements */
+static int n_measurements = 0;
+static struct cached_bw_event_s {
+ uint32_t n_read;
+ uint32_t n_written;
+} cached_bw_events[N_BW_EVENTS_TO_CACHE];
+
/** A second or more has elapsed: tell any interested control
* connections how much bandwidth we used. */
int
control_event_bandwidth_used(uint32_t n_read, uint32_t n_written)
{
+ cached_bw_events[next_measurement_idx].n_read = n_read;
+ cached_bw_events[next_measurement_idx].n_written = n_written;
+ if (++next_measurement_idx == N_BW_EVENTS_TO_CACHE)
+ next_measurement_idx = 0;
+ if (n_measurements < N_BW_EVENTS_TO_CACHE)
+ ++n_measurements;
+
if (EVENT_IS_INTERESTING(EVENT_BANDWIDTH_USED)) {
send_control_event(EVENT_BANDWIDTH_USED, ALL_FORMATS,
"650 BW %lu %lu\r\n",
@@ -4148,6 +4169,38 @@ control_event_bandwidth_used(uint32_t n_read, uint32_t n_written)
return 0;
}
+STATIC char *
+get_bw_samples(void)
+{
+ int i;
+ int idx = (next_measurement_idx + N_BW_EVENTS_TO_CACHE - n_measurements)
+ % N_BW_EVENTS_TO_CACHE;
+ smartlist_t *elements = smartlist_new();
+ tor_assert(0 <= idx && idx < N_BW_EVENTS_TO_CACHE);
+
+ for (i = 0; i < n_measurements; ++i) {
+ tor_assert(0 <= idx && idx < N_BW_EVENTS_TO_CACHE);
+ {
+ const struct cached_bw_event_s *bwe = &cached_bw_events[idx];
+
+ smartlist_add_asprintf(elements, "%u,%u",
+ (unsigned)bwe->n_read,
+ (unsigned)bwe->n_written);
+
+ idx = (idx + 1) % N_BW_EVENTS_TO_CACHE;
+ }
+ }
+
+ {
+ char *result = smartlist_join_strings(elements, " ", 0, NULL);
+
+ SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
+ smartlist_free(elements);
+
+ return result;
+ }
+}
+
/** Called when we are sending a log message to the controllers: suspend
* sending further log messages to the controllers until we're done. Used by
* CONN_LOG_PROTECT. */
diff --git a/src/or/control.h b/src/or/control.h
index 494f04b3b..869726217 100644
--- a/src/or/control.h
+++ b/src/or/control.h
@@ -201,6 +201,7 @@ void append_cell_stats_by_command(smartlist_t *event_parts,
const uint64_t *number_to_include);
void format_cell_stats(char **event_string, circuit_t *circ,
cell_stats_t *cell_stats);
+STATIC char *get_bw_samples(void);
#endif
#endif
diff --git a/src/or/directory.c b/src/or/directory.c
index 298271f36..50863d0c7 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -2183,12 +2183,15 @@ connection_dir_reached_eof(dir_connection_t *conn)
*/
#define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
+#define MAX_VOTE_DL_SIZE (MAX_DIRECTORY_OBJECT_SIZE * 5)
+
/** Read handler for directory connections. (That's connections to
* directory servers and connections at directory servers.)
*/
int
connection_dir_process_inbuf(dir_connection_t *conn)
{
+ size_t max_size;
tor_assert(conn);
tor_assert(conn->base_.type == CONN_TYPE_DIR);
@@ -2207,7 +2210,11 @@ connection_dir_process_inbuf(dir_connection_t *conn)
return 0;
}
- if (connection_get_inbuf_len(TO_CONN(conn)) > MAX_DIRECTORY_OBJECT_SIZE) {
+ max_size =
+ (TO_CONN(conn)->purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) ?
+ MAX_VOTE_DL_SIZE : MAX_DIRECTORY_OBJECT_SIZE;
+
+ if (connection_get_inbuf_len(TO_CONN(conn)) > max_size) {
log_warn(LD_HTTP, "Too much data received from directory connection: "
"denial of service attempt, or you need to upgrade?");
connection_mark_for_close(TO_CONN(conn));
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 49fafafab..03b32cb2f 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -2487,7 +2487,7 @@ int
dirserv_read_measured_bandwidths(const char *from_file,
smartlist_t *routerstatuses)
{
- char line[256];
+ char line[512];
FILE *fp = tor_fopen_cloexec(from_file, "r");
int applied_lines = 0;
time_t file_time, now;
diff --git a/src/or/dns.c b/src/or/dns.c
index a9c431865..b55bf7384 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -558,6 +558,8 @@ purge_expired_resolves(time_t now)
/* Connections should only be pending if they have no socket. */
tor_assert(!SOCKET_OK(pend->conn->base_.s));
pendconn = pend->conn;
+ /* Prevent double-remove */
+ pendconn->base_.state = EXIT_CONN_STATE_RESOLVEFAILED;
if (!pendconn->base_.marked_for_close) {
connection_edge_end(pendconn, END_STREAM_REASON_TIMEOUT);
circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn);
@@ -1133,7 +1135,9 @@ connection_dns_remove(edge_connection_t *conn)
return; /* more are pending */
}
}
- tor_assert(0); /* not reachable unless onlyconn not in pending list */
+ log_warn(LD_BUG, "Connection (fd "TOR_SOCKET_T_FORMAT") was not waiting "
+ "for a resolve of %s, but we tried to remove it.",
+ conn->base_.s, escaped_safe_str(conn->base_.address));
}
}
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 72de54c0c..cedc56af0 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -1131,9 +1131,7 @@ rep_hist_load_mtbf_data(time_t now)
* totals? */
#define NUM_SECS_ROLLING_MEASURE 10
/** How large are the intervals for which we track and report bandwidth use? */
-/* XXXX Watch out! Before Tor 0.2.2.21-alpha, using any other value here would
- * generate an unparseable state file. */
-#define NUM_SECS_BW_SUM_INTERVAL (15*60)
+#define NUM_SECS_BW_SUM_INTERVAL (4*60*60)
/** How far in the past do we remember and publish bandwidth use? */
#define NUM_SECS_BW_SUM_IS_VALID (24*60*60)
/** How many bandwidth usage intervals do we remember? (derived) */
diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c
index 5deb36260..9aff6ab49 100644
--- a/src/test/test_relaycell.c
+++ b/src/test/test_relaycell.c
@@ -104,7 +104,7 @@ test_relaycell_resolved(void *arg)
tt_int_op(srm_answer_is_set, ==, 0); \
} \
tt_int_op(srm_ttl, ==, ttl); \
- tt_int_op(srm_expires, ==, expires); \
+ tt_i64_op((int64_t)srm_expires, ==, (int64_t)expires); \
} while (0)
(void)arg;
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 151ec6912..225fb790f 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -3741,7 +3741,7 @@ test_util_max_mem(void *arg)
} else {
/* You do not have a petabyte. */
#if SIZEOF_SIZE_T == SIZEOF_UINT64_T
- tt_uint_op(memory1, <, (U64_LITERAL(1)<<50));
+ tt_u64_op(memory1, <, (U64_LITERAL(1)<<50));
#endif
}