[tor-commits] [tor/maint-0.4.5] TROVE-2021-003: Check layer_hint before half-closed end and resolve cells

nickm at torproject.org nickm at torproject.org
Mon Jun 14 15:03:33 UTC 2021


commit adb248b6d6e0779719e6b873ee12a1e22fa390f4
Author: David Goulet <dgoulet at torproject.org>
Date:   Thu Jun 3 09:33:21 2021 -0400

    TROVE-2021-003: Check layer_hint before half-closed end and resolve cells
    
    This issue was reported by Jann Horn part of Google's Project Zero.
    
    Jann's one-sentence summary: entry/middle relays can spoof RELAY_END cells on
    half-closed streams, which can lead to stream confusion between OP and
    exit.
    
    Fixes #40389
---
 changes/ticket40389 |  3 +++
 src/core/or/relay.c | 25 +++++++++++++++++++++++--
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/changes/ticket40389 b/changes/ticket40389
new file mode 100644
index 0000000000..7dcf65b32e
--- /dev/null
+++ b/changes/ticket40389
@@ -0,0 +1,3 @@
+  o Major bugfixes (relay, TROVE):
+    - Don't allow entry or middle relays to spoof RELAY_END or RELAY_RESOLVED
+      cell on half-closed streams. Fixes bug 40389; bugfix on 0.3.5.1-alpha.
diff --git a/src/core/or/relay.c b/src/core/or/relay.c
index f5fc1cfbb3..00353f47a9 100644
--- a/src/core/or/relay.c
+++ b/src/core/or/relay.c
@@ -1428,6 +1428,25 @@ connection_edge_process_relay_cell_not_open(
 //  return -1;
 }
 
+/**
+ * Return true iff our decryption layer_hint is from the last hop
+ * in a circuit.
+ */
+static bool
+relay_crypt_from_last_hop(origin_circuit_t *circ, crypt_path_t *layer_hint)
+{
+  tor_assert(circ);
+  tor_assert(layer_hint);
+  tor_assert(circ->cpath);
+
+  if (layer_hint != circ->cpath->prev) {
+    log_fn(LOG_PROTOCOL_WARN, LD_CIRC,
+           "Got unexpected relay data from intermediate hop");
+    return false;
+  }
+  return true;
+}
+
 /** An incoming relay cell has arrived on circuit <b>circ</b>. If
  * <b>conn</b> is NULL this is a control cell, else <b>cell</b> is
  * destined for <b>conn</b>.
@@ -1616,7 +1635,8 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
       if (!conn) {
         if (CIRCUIT_IS_ORIGIN(circ)) {
           origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
-          if (connection_half_edge_is_valid_end(ocirc->half_streams,
+          if (relay_crypt_from_last_hop(ocirc, layer_hint) &&
+              connection_half_edge_is_valid_end(ocirc->half_streams,
                                                 rh.stream_id)) {
 
             circuit_read_valid_data(ocirc, rh.length);
@@ -1918,7 +1938,8 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
 
       if (CIRCUIT_IS_ORIGIN(circ)) {
         origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
-        if (connection_half_edge_is_valid_resolved(ocirc->half_streams,
+        if (relay_crypt_from_last_hop(ocirc, layer_hint) &&
+            connection_half_edge_is_valid_resolved(ocirc->half_streams,
                                                     rh.stream_id)) {
           circuit_read_valid_data(ocirc, rh.length);
           log_info(domain,





More information about the tor-commits mailing list