[tor-commits] [tor/maint-0.2.3] When iterating over connections pending DNS, skip marked ones

nickm at torproject.org nickm at torproject.org
Fri Aug 24 16:51:45 UTC 2012


commit 223e7cfabec5a75a7acd919210f838511e39cb16
Author: Nick Mathewson <nickm at torproject.org>
Date:   Fri Aug 17 16:46:11 2012 -0400

    When iterating over connections pending DNS, skip marked ones
    
    Failure to do this would lead to double-free cases and similar,
    especially when the exit's DNS was broken. See bug 6472 for full
    details; this is a fix for 6472.
    
    Anonymous patch from "cypherpunks" on trac.
---
 changes/bug6472 |    4 ++++
 src/or/dns.c    |   16 ++++++++++++----
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/changes/bug6472 b/changes/bug6472
new file mode 100644
index 0000000..dcd42eb
--- /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/src/or/dns.c b/src/or/dns.c
index 3e88fad..78893bf 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;
 





More information about the tor-commits mailing list