Commit 9acca040 authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Merge branch 'maint-0.3.0'

parents 5955b63a 0c46dc80
Loading
Loading
Loading
Loading

changes/trove-2017-004

0 → 100644
+8 −0
Original line number Diff line number Diff line
  o Major bugfixes (hidden service, relay, security):
    - Fix an assertion failure when an hidden service handles a
      malformed BEGIN cell. This bug resulted in the service crashing
      triggered by a tor_assert(). Fixes bug 22493, tracked as
      TROVE-2017-004 and as CVE-2017-0375; bugfix on tor-0.3.0.1-alpha.
      Found by armadev.

+14 −7
Original line number Diff line number Diff line
@@ -3092,14 +3092,21 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
  char *address = NULL;
  uint16_t port = 0;
  or_circuit_t *or_circ = NULL;
  origin_circuit_t *origin_circ = NULL;
  crypt_path_t *layer_hint = NULL;
  const or_options_t *options = get_options();
  begin_cell_t bcell;
  int rv;
  uint8_t end_reason=0;

  assert_circuit_ok(circ);
  if (!CIRCUIT_IS_ORIGIN(circ))
  if (!CIRCUIT_IS_ORIGIN(circ)) {
    or_circ = TO_OR_CIRCUIT(circ);
  } else {
    tor_assert(circ->purpose == CIRCUIT_PURPOSE_S_REND_JOINED);
    origin_circ = TO_ORIGIN_CIRCUIT(circ);
    layer_hint = origin_circ->cpath->prev;
  }

  relay_header_unpack(&rh, cell->payload);
  if (rh.length > RELAY_PAYLOAD_SIZE)
@@ -3124,7 +3131,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
    return -END_CIRC_REASON_TORPROTOCOL;
  } else if (rv == -1) {
    tor_free(bcell.address);
    relay_send_end_cell_from_edge(rh.stream_id, circ, end_reason, NULL);
    relay_send_end_cell_from_edge(rh.stream_id, circ, end_reason, layer_hint);
    return 0;
  }

@@ -3159,7 +3166,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
    if (!directory_permits_begindir_requests(options) ||
        circ->purpose != CIRCUIT_PURPOSE_OR) {
      relay_send_end_cell_from_edge(rh.stream_id, circ,
                                    END_STREAM_REASON_NOTDIRECTORY, NULL);
                                  END_STREAM_REASON_NOTDIRECTORY, layer_hint);
      return 0;
    }
    /* Make sure to get the 'real' address of the previous hop: the
@@ -3176,7 +3183,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
  } else {
    log_warn(LD_BUG, "Got an unexpected command %d", (int)rh.command);
    relay_send_end_cell_from_edge(rh.stream_id, circ,
                                  END_STREAM_REASON_INTERNAL, NULL);
                                  END_STREAM_REASON_INTERNAL, layer_hint);
    return 0;
  }

@@ -3187,7 +3194,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
    if (bcell.flags & BEGIN_FLAG_IPV4_NOT_OK) {
      tor_free(address);
      relay_send_end_cell_from_edge(rh.stream_id, circ,
                                    END_STREAM_REASON_EXITPOLICY, NULL);
                                    END_STREAM_REASON_EXITPOLICY, layer_hint);
      return 0;
    }
  }
@@ -3210,7 +3217,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
  n_stream->deliver_window = STREAMWINDOW_START;

  if (circ->purpose == CIRCUIT_PURPOSE_S_REND_JOINED) {
    origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
    tor_assert(origin_circ);
    log_info(LD_REND,"begin is for rendezvous. configuring stream.");
    n_stream->base_.address = tor_strdup("(rendezvous)");
    n_stream->base_.state = EXIT_CONN_STATE_CONNECTING;
@@ -3230,7 +3237,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
       * the hidden service. */
      relay_send_end_cell_from_edge(rh.stream_id, circ,
                                    END_STREAM_REASON_DONE,
                                    origin_circ->cpath->prev);
                                    layer_hint);
      connection_free(TO_CONN(n_stream));
      tor_free(address);