summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2006-12-29 05:07:25 +0000
committerNick Mathewson <nickm@torproject.org>2006-12-29 05:07:25 +0000
commit0e172d9f6e0f6b1fbe20618879b892662a7dc051 (patch)
treebb3c41c20ab07fd7796919aa2c38f74563c3b38d
parent8728e2826f9a06a842b77876b8a616ae394ecdb1 (diff)
downloadtor-0e172d9f6e0f6b1fbe20618879b892662a7dc051.tar.gz
tor-0e172d9f6e0f6b1fbe20618879b892662a7dc051.zip
r11745@Kushana: nickm | 2006-12-29 00:00:28 -0500
Close any directory connection on which we have received 10MB or more of data. This prevents a malicious directory cache from running us out of memory by spooling an infinite amount of data. (Not a terribly good attack, but hey, every one helps.) svn:r9210
-rw-r--r--ChangeLog1
-rw-r--r--src/or/directory.c13
2 files changed, 13 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index f84c6ee1ba..773aa8bfec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -75,6 +75,7 @@ Changes in version 0.1.2.5-xxxx - 200?-??-??
it's happening. (Bug #364)
- When we change nameservers or IP addresses, reset and re-launch
our tests for DNS hijacking.
+ - Block an obscure DoS attack from directory caches.
o Security bugfixes:
- Stop sending the HttpProxyAuthenticator string to directory
diff --git a/src/or/directory.c b/src/or/directory.c
index 17deef93eb..57f0871475 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -1283,6 +1283,12 @@ connection_dir_reached_eof(dir_connection_t *conn)
return retval;
}
+/** If any directory object is arriving, and it's over 10MB large, we're
+ * getting DoS'd. (As of 0.1.2.x, raw directories are about 1MB, and we never
+ * ask for more than 96 router descriptors at a time.)
+ */
+#define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
+
/** Read handler for directory connections. (That's connections <em>to</em>
* directory servers and connections <em>at</em> directory servers.)
*/
@@ -1307,7 +1313,12 @@ connection_dir_process_inbuf(dir_connection_t *conn)
return 0;
}
- /* XXXX012 for READ states, might want to make sure inbuf isn't too big */
+ if (buf_datalen(conn->_base.inbuf) > MAX_DIRECTORY_OBJECT_SIZE) {
+ log_warn(LD_HTTP, "Too much data received from directory connection; "
+ "DOS attempt or protocol shift.");
+ connection_mark_for_close(TO_CONN(conn));
+ return -1;
+ }
if (!conn->_base.inbuf_reached_eof)
log_debug(LD_HTTP,"Got data, not eof. Leaving on inbuf.");