]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
hs-v3: Remove a BUG() caused by an acceptable race
authorDavid Goulet <dgoulet@torproject.org>
Wed, 23 Oct 2019 14:20:09 +0000 (10:20 -0400)
committerDavid Goulet <dgoulet@torproject.org>
Thu, 24 Oct 2019 12:50:01 +0000 (08:50 -0400)
hs_client_purge_state() and hs_cache_clean_as_client() can remove a descriptor
from the client cache with a NEWNYM or simply when the descriptor expires.

Which means that for an INTRO circuit being established during that time, once
it opens, we lookup the descriptor to get the IP object but hey surprised, no
more descriptor.

The approach here is minimalist that is accept the race and close the circuit
since we can not continue. Before that, the circuit would stay opened and the
client wait the SockTimeout.

Fixers #28970.

Signed-off-by: David Goulet <dgoulet@torproject.org>
changes/ticket28970 [new file with mode: 0644]
src/feature/hs/hs_client.c

diff --git a/changes/ticket28970 b/changes/ticket28970
new file mode 100644 (file)
index 0000000..138c575
--- /dev/null
@@ -0,0 +1,6 @@
+  o Minor bugfixes (clietn, hidden service v3):
+    - Fix a BUG() assertion that occurs within a very small race window between
+      a client intro circuit opens and its descriptor that gets cleaned up from
+      the cache. The circuit is now closed which will trigger a re-fetch of the
+      descriptor and continue the HS connection. Fixes bug 28970; bugfix on
+      0.3.2.1-alpha.
index 2a5765aec203bc7e5e965e833c64ad12fdeab69a..fd2d266453821722dbeb6736ac1d6d7e3a1ed549 100644 (file)
@@ -672,8 +672,12 @@ setup_intro_circ_auth_key(origin_circuit_t *circ)
   tor_assert(circ);
 
   desc = hs_cache_lookup_as_client(&circ->hs_ident->identity_pk);
-  if (BUG(desc == NULL)) {
-    /* Opening intro circuit without the descriptor is no good... */
+  if (desc == NULL) {
+    /* There is a very small race window between the opening of this circuit
+     * and the client descriptor cache that gets purged (NEWNYM) or the
+     * cleaned up because it expired. Mark the circuit for close so a new
+     * descriptor fetch can occur. */
+    circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_INTERNAL);
     goto end;
   }