mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
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
This commit is contained in:
committed by
Nick Mathewson
parent
d71bf986b4
commit
adb248b6d6
@@ -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.
|
||||
+23
-2
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user