]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Kill non-open OR connections with any data on their inbufs.
authorNick Mathewson <nickm@torproject.org>
Thu, 31 May 2012 15:19:35 +0000 (11:19 -0400)
committerNick Mathewson <nickm@torproject.org>
Mon, 4 Jun 2012 15:29:18 +0000 (11:29 -0400)
This fixes a DoS issue where a client could send so much data in 5
minutes that they exhausted the server's RAM.  Fix for bug 5934 and
6007.  Bugfix on 0.2.0.20-rc, which enabled the v2 handshake.

changes/bug6007 [new file with mode: 0644]
src/or/connection_or.c

diff --git a/changes/bug6007 b/changes/bug6007
new file mode 100644 (file)
index 0000000..4e81575
--- /dev/null
@@ -0,0 +1,5 @@
+  o Major bugfixes (security):
+    - When waiting for a client to renegotiate, don't allow it to add
+      any bytes to the input buffer. This fixes a DoS issue. Fix for
+      bugs 6007 and 5934; bugfix on 0.2.0.20-rc.
+
index dc8850ea3fdead956084bd0e4d83f6c443d2ba77..cb0082bdc2680397bae58fb7e38ae14bee82944e 100644 (file)
@@ -209,7 +209,12 @@ connection_or_reached_eof(or_connection_t *conn)
 int
 connection_or_process_inbuf(or_connection_t *conn)
 {
-  int ret;
+  /** Don't let the inbuf of a nonopen OR connection grow beyond this many
+   * bytes: it's either a broken client, a non-Tor client, or a DOS
+   * attempt. */
+#define MAX_OR_INBUF_WHEN_NONOPEN 0
+
+  int ret = 0;
   tor_assert(conn);
 
   switch (conn->_base.state) {
@@ -231,8 +236,21 @@ connection_or_process_inbuf(or_connection_t *conn)
     case OR_CONN_STATE_OR_HANDSHAKING:
       return connection_or_process_cells_from_inbuf(conn);
     default:
-      return 0; /* don't do anything */
+      break; /* don't do anything */
   }
+
+  if (buf_datalen(conn->_base.inbuf) > MAX_OR_INBUF_WHEN_NONOPEN) {
+    log_fn(LOG_PROTOCOL_WARN, LD_NET, "Accumulated too much data (%d bytes) "
+          "on nonopen OR connection %s %s:%u in state %s; closing.",
+          (int)buf_datalen(conn->_base.inbuf),
+          connection_or_nonopen_was_started_here(conn) ? "to" : "from",
+          conn->_base.address, conn->_base.port,
+          conn_state_to_string(conn->_base.type, conn->_base.state));
+    connection_mark_for_close(TO_CONN(conn));
+    ret = -1;
+  }
+
+  return ret;
 }
 
 /** When adding cells to an OR connection's outbuf, keep adding until the