[tor-commits] [tor/release-0.3.2] dos: Apply defense for circuit creation DoS

nickm at torproject.org nickm at torproject.org
Fri Feb 16 14:56:21 UTC 2018


commit 1bfc91a029839f36e04c8204d1bccaa04a5c2afd
Author: David Goulet <dgoulet at torproject.org>
Date:   Thu Jan 25 16:20:52 2018 -0500

    dos: Apply defense for circuit creation DoS
    
    If the client address was detected as malicious, apply a defense which is at
    this commit to return a DESTROY cell.
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 src/or/command.c |  7 ++++++
 src/or/dos.c     | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/or/dos.h     |  1 +
 3 files changed, 73 insertions(+)

diff --git a/src/or/command.c b/src/or/command.c
index d2df55a4b..0d2808e23 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -290,6 +290,13 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
     return;
   }
 
+  /* Check if we should apply a defense for this channel. */
+  if (dos_cc_get_defense_type(chan) == DOS_CC_DEFENSE_REFUSE_CELL) {
+    channel_send_destroy(cell->circ_id, chan,
+                         END_CIRC_REASON_RESOURCELIMIT);
+    return;
+  }
+
   if (!server_mode(options) ||
       (!public_server_mode(options) && channel_is_outgoing(chan))) {
     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
diff --git a/src/or/dos.c b/src/or/dos.c
index b83ea6029..8c00a2f31 100644
--- a/src/or/dos.c
+++ b/src/or/dos.c
@@ -36,6 +36,7 @@ static dos_cc_defense_type_t dos_cc_defense_type;
 static int32_t dos_cc_defense_time_period;
 
 /* Keep some stats for the heartbeat so we can report out. */
+static uint64_t cc_num_rejected_cells;
 static uint32_t cc_num_marked_addrs;
 
 /*
@@ -323,6 +324,44 @@ cc_mark_client(cc_client_stats_t *stats)
     crypto_rand_int_range(1, dos_cc_defense_time_period / 2);
 }
 
+/* Return true iff the given channel address is marked as malicious. This is
+ * called a lot and part of the fast path of handling cells. It has to remain
+ * as fast as we can. */
+static int
+cc_channel_addr_is_marked(channel_t *chan)
+{
+  time_t now;
+  tor_addr_t addr;
+  clientmap_entry_t *entry;
+  cc_client_stats_t *stats = NULL;
+
+  if (chan == NULL) {
+    goto end;
+  }
+  /* Must be a client connection else we ignore. */
+  if (!channel_is_client(chan)) {
+    goto end;
+  }
+  /* Without an IP address, nothing can work. */
+  if (!channel_get_addr_if_possible(chan, &addr)) {
+    goto end;
+  }
+
+  /* We are only interested in client connection from the geoip cache. */
+  entry = geoip_lookup_client(&addr, NULL, GEOIP_CLIENT_CONNECT);
+  if (entry == NULL) {
+    /* We can have a connection creating circuits but not tracked by the geoip
+     * cache. Once this DoS subsystem is enabled, we can end up here with no
+     * entry for the channel. */
+    goto end;
+  }
+  now = approx_time();
+  stats = &entry->dos_stats.cc_stats;
+
+ end:
+  return stats && stats->marked_until_ts >= now;
+}
+
 /* Concurrent connection private API. */
 
 /* Free everything for the connection DoS mitigation subsystem. */
@@ -421,6 +460,32 @@ dos_cc_new_create_cell(channel_t *chan)
   return;
 }
 
+/* Return the defense type that should be used for this circuit.
+ *
+ * This is part of the fast path and called a lot. */
+dos_cc_defense_type_t
+dos_cc_get_defense_type(channel_t *chan)
+{
+  tor_assert(chan);
+
+  /* Skip everything if not enabled. */
+  if (!dos_cc_enabled) {
+    goto end;
+  }
+
+  /* On an OR circuit, we'll check if the previous channel is a marked client
+   * connection detected by our DoS circuit creation mitigation subsystem. */
+  if (cc_channel_addr_is_marked(chan)) {
+    /* We've just assess that this circuit should trigger a defense for the
+     * cell it just seen. Note it down. */
+    cc_num_rejected_cells++;
+    return dos_cc_defense_type;
+  }
+
+ end:
+  return DOS_CC_DEFENSE_NONE;
+}
+
 /* Concurrent connection detection public API. */
 
 /* General API */
diff --git a/src/or/dos.h b/src/or/dos.h
index bb8d7d1a7..fa86295cf 100644
--- a/src/or/dos.h
+++ b/src/or/dos.h
@@ -81,6 +81,7 @@ typedef enum dos_cc_defense_type_t {
 } dos_cc_defense_type_t;
 
 void dos_cc_new_create_cell(channel_t *channel);
+dos_cc_defense_type_t dos_cc_get_defense_type(channel_t *chan);
 
 /*
  * Concurrent connection DoS mitigation interface.





More information about the tor-commits mailing list