aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2021-06-10 08:52:39 -0400
committerNick Mathewson <nickm@torproject.org>2021-06-10 08:52:39 -0400
commit0f2d45328dfcb16acb4a517711413a6f0386487a (patch)
treebe10b1fdcc6aa2291b2c587f46cfce1ee3dacd2d
parent31eaa81f59749ed7e9d4f1bad24225d23eb6f654 (diff)
parentadb248b6d6e0779719e6b873ee12a1e22fa390f4 (diff)
downloadtor-0f2d45328dfcb16acb4a517711413a6f0386487a.tar.gz
tor-0f2d45328dfcb16acb4a517711413a6f0386487a.zip
Merge branch 'maint-0.3.5' into maint-0.4.4
Conflicts resolved: src/core/or/relay.c
-rw-r--r--changes/ticket403893
-rw-r--r--src/core/or/relay.c39
2 files changed, 42 insertions, 0 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 75d2d479e7..78fda99a45 100644
--- a/src/core/or/relay.c
+++ b/src/core/or/relay.c
@@ -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);