aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2012-05-31 11:19:35 -0400
committerNick Mathewson <nickm@torproject.org>2012-06-04 11:29:18 -0400
commitaf54a0182870babec62bf07d067ca82a67c423de (patch)
tree4515797b262d2b6e8c20daaa93f8d82389ef34c6
parent3a9351b57e528b1d0bd2e72bcf78db7c91b2ff8f (diff)
downloadtor-af54a0182870babec62bf07d067ca82a67c423de.tar.gz
tor-af54a0182870babec62bf07d067ca82a67c423de.zip
Kill non-open OR connections with any data on their inbufs.
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.
-rw-r--r--changes/bug60075
-rw-r--r--src/or/connection_or.c22
2 files changed, 25 insertions, 2 deletions
diff --git a/changes/bug6007 b/changes/bug6007
new file mode 100644
index 0000000000..4e815754aa
--- /dev/null
+++ b/changes/bug6007
@@ -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.
+
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index dc8850ea3f..cb0082bdc2 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -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