Merge remote-tracking branch 'origin/maint-0.2.3'

This commit is contained in:
Nick Mathewson 2012-08-24 12:51:50 -04:00
commit 6864a44a4a
2 changed files with 16 additions and 4 deletions

4
changes/bug6472 Normal file
View File

@ -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.

View File

@ -450,16 +450,17 @@ purge_expired_resolves(time_t now)
if (resolve->pending_connections) { if (resolve->pending_connections) {
log_debug(LD_EXIT, log_debug(LD_EXIT,
"Closing pending connections on timed-out DNS resolve!"); "Closing pending connections on timed-out DNS resolve!");
tor_fragile_assert();
while (resolve->pending_connections) { while (resolve->pending_connections) {
pend = resolve->pending_connections; pend = resolve->pending_connections;
resolve->pending_connections = pend->next; resolve->pending_connections = pend->next;
/* Connections should only be pending if they have no socket. */ /* Connections should only be pending if they have no socket. */
tor_assert(!SOCKET_OK(pend->conn->_base.s)); tor_assert(!SOCKET_OK(pend->conn->_base.s));
pendconn = pend->conn; pendconn = pend->conn;
if (!pendconn->_base.marked_for_close) {
connection_edge_end(pendconn, END_STREAM_REASON_TIMEOUT); connection_edge_end(pendconn, END_STREAM_REASON_TIMEOUT);
circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn); circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn);
connection_free(TO_CONN(pendconn)); connection_free(TO_CONN(pendconn));
}
tor_free(pend); 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 pendconn = pend->conn; /* don't pass complex things to the
connection_mark_for_close macro */ connection_mark_for_close macro */
assert_connection_ok(TO_CONN(pendconn),time(NULL)); 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); tor_addr_from_ipv4h(&pendconn->_base.addr, addr);
pendconn->address_ttl = ttl; pendconn->address_ttl = ttl;