[tor-bugs] #23603 [Core Tor/Tor]: hs: Cleanup race between circuit close and free with the HS circuitmap
Tor Bug Tracker & Wiki
blackhole at torproject.org
Wed Sep 20 15:26:08 UTC 2017
#23603: hs: Cleanup race between circuit close and free with the HS circuitmap
------------------------------+--------------------------------
Reporter: dgoulet | Owner: (none)
Type: defect | Status: new
Priority: High | Milestone: Tor: 0.3.2.x-final
Component: Core Tor/Tor | Version:
Severity: Normal | Keywords: tor-hs
Actual Points: | Parent ID:
Points: | Reviewer:
Sponsor: |
------------------------------+--------------------------------
Here is the scenario that has been encountered by asn. The following is in
chronological order:
1. [02:21:27] An intro point (IP) is picked and circuit A is launched.
2. [02:23:47] Circuit A never completes and thus is '''marked for close'''
which is NOT free thus still in our HS circuitmap.
2. [02:23:48] A second later, the HS housekeeping kicks in (every 1 sec)
and we notice that we are missing a circuit for this IP so we launch a new
circuit B. What happens then is this new circuit B takes the place of
circuit A in the HS circuitmap with the *same* hs_token (the token in this
case is the IP authentication public key).
At this point, we have circuit A marked for close and we have circuit B
that was launched and replaced circuit A with the same hs_token which
identify the IP. So far so good.
3. [02:23:48] At the same second, we get a `circuit_build_failed()` which
is only called from
`circuit_about_to_free()`->`circuit_close_all_marked()` which means it is
freeing circuit '''A''' leading to a `hs_circuitmap_remove_circuit()`
which will use its `hs_token` to remove circuit B because it is the same
token.
We end up with no circuit for the intro point IP in our circuitmap.
4. [02:23:49] A second after our circuit build failed which removed
circuit B from the circuitmap, we cleanup the IP from our list through the
house keeping and we launch a new circuit to a new intro point. The reason
why we removed the IP is either because it has expire, no `node_t` could
be found or we retried too many times on that circuit which the allowed
number of retries is 3 right now. When we do remove an IP from our service
list, we also try to close the circuit but because circuit B got removed
from the circuitmap, we can't find it thus it is not closed.
5. [02:24:54] Circuit B completes but we are unable to find the IP in our
service list. And boom we get the warning:
In summary, we end up with an intro circuit being established but not in
our circuitmap leading to the failed lookup when we remove that IP from
our service list for whatever reason.
Seems like one thing we could do is actually remove a circuit from the HS
circuitmap when we mark for close because at that point, the circuit is
good as dead. We avoid this race between mark for close and actually being
freed where in between a new circuit to the same destination with the same
hs_token can be launched.
--
Ticket URL: <https://trac.torproject.org/projects/tor/ticket/23603>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online
More information about the tor-bugs
mailing list