diff options
author | Nick Mathewson <nickm@torproject.org> | 2012-05-31 11:19:35 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2012-06-04 11:29:18 -0400 |
commit | af54a0182870babec62bf07d067ca82a67c423de (patch) | |
tree | 4515797b262d2b6e8c20daaa93f8d82389ef34c6 | |
parent | 3a9351b57e528b1d0bd2e72bcf78db7c91b2ff8f (diff) | |
download | tor-af54a0182870babec62bf07d067ca82a67c423de.tar tor-af54a0182870babec62bf07d067ca82a67c423de.tar.gz |
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/bug6007 | 5 | ||||
-rw-r--r-- | src/or/connection_or.c | 22 |
2 files changed, 25 insertions, 2 deletions
diff --git a/changes/bug6007 b/changes/bug6007 new file mode 100644 index 000000000..4e815754a --- /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 dc8850ea3..cb0082bdc 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 |