Commit 0f2d4532 authored by Nick Mathewson's avatar Nick Mathewson 🥔
Browse files

Merge branch 'maint-0.3.5' into maint-0.4.4

Conflicts resolved:
	src/core/or/relay.c
parents 31eaa81f adb248b6
Loading
Loading
Loading
Loading

changes/ticket40389

0 → 100644
+3 −0
Original line number Diff line number Diff line
  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.
+39 −0
Original line number Diff line number Diff line
@@ -1503,6 +1503,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;
}

/** Process a SENDME cell that arrived on <b>circ</b>. If it is a stream level
 * cell, it is destined for the given <b>conn</b>. If it is a circuit level
 * cell, it is destined for the <b>layer_hint</b>. The <b>domain</b> is the
@@ -1716,8 +1735,17 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,
      if (!conn) {
        if (CIRCUIT_IS_ORIGIN(circ)) {
          origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
<<<<<<< HEAD
          if (connection_half_edge_is_valid_end(ocirc->half_streams,
                                                rh->stream_id)) {
||||||| d71bf986b4faf7
          if (connection_half_edge_is_valid_end(ocirc->half_streams,
                                                rh.stream_id)) {
=======
          if (relay_crypt_from_last_hop(ocirc, layer_hint) &&
              connection_half_edge_is_valid_end(ocirc->half_streams,
                                                rh.stream_id)) {
>>>>>>> maint-0.3.5

            circuit_read_valid_data(ocirc, rh->length);
            log_info(domain,
@@ -1926,9 +1954,20 @@ handle_relay_cell_command(cell_t *cell, circuit_t *circ,

      if (CIRCUIT_IS_ORIGIN(circ)) {
        origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
<<<<<<< HEAD
        if (connection_half_edge_is_valid_resolved(ocirc->half_streams,
                                                    rh->stream_id)) {
          circuit_read_valid_data(ocirc, rh->length);
||||||| d71bf986b4faf7
        if (connection_half_edge_is_valid_resolved(ocirc->half_streams,
                                                    rh.stream_id)) {
          circuit_read_valid_data(ocirc, rh.length);
=======
        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);
>>>>>>> maint-0.3.5
          log_info(domain,
                   "resolved cell on circ %u valid on half-closed "
                   "stream id %d", ocirc->global_identifier, rh->stream_id);