aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--src/or/dirserv.c30
-rw-r--r--src/or/or.h8
3 files changed, 42 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 0c4ff8223..ea51028f5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,4 @@
-Changes in version 0.2.0.13-alpha - 2007-11-??
+Changes in version 0.2.0.13-alpha - 2007-12-??
o Major bugfixes:
- Only update guard status (usable / not usable) once we have
enough directory information. This was causing us to always pick
@@ -21,6 +21,9 @@ Changes in version 0.2.0.13-alpha - 2007-11-??
crashed if we had tried to parse one). Bugfix on 0.2.0.x; patch
by Karsten Loesing.
- Fix building with dmalloc 5.5.2 with glibc.
+ - Reject uploaded descriptors and extrainfo documents if they're
+ huge. Otherwise we'll cache them all over the network and it'll
+ clog everything up.
o Minor features:
- On USR1, when dmalloc is in use, log the top 10 memory
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index b48dd142a..e4299fba9 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -640,6 +640,22 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg)
char *desc = NULL;
size_t desclen = 0;
+ /* If it's too big, refuse it now. Otherwise we'll cache it all over the
+ * network and it'll clog everything up. */
+ if (ri->cache_info.signed_descriptor_len > MAX_DESCRIPTOR_UPLOAD_SIZE) {
+ log_notice(LD_DIR, "Somebody attempted to publish a router descriptor "
+ "with size %d. Either this is an attack, or the "
+ "MAX_DESCRIPTOR_UPLOAD_SIZE (%d) constant is too low.",
+ (int)ri->cache_info.signed_descriptor_len,
+ MAX_DESCRIPTOR_UPLOAD_SIZE);
+ *msg = "Router descriptor was too large";
+ control_event_or_authdir_new_descriptor("REJECTED",
+ ri->cache_info.signed_descriptor_body,
+ ri->cache_info.signed_descriptor_len, *msg);
+ routerinfo_free(ri);
+ return -1;
+ }
+
/* Check whether this descriptor is semantically identical to the last one
* from this server. (We do this here and not in router_add_to_routerlist
* because we want to be able to accept the newest router descriptor that
@@ -703,6 +719,20 @@ dirserv_add_extrainfo(extrainfo_t *ei, const char **msg)
extrainfo_free(ei);
return -1;
}
+
+ /* If it's too big, refuse it now. Otherwise we'll cache it all over the
+ * network and it'll clog everything up. */
+ if (ei->cache_info.signed_descriptor_len > MAX_EXTRAINFO_UPLOAD_SIZE) {
+ log_notice(LD_DIR, "Somebody attempted to publish an extrainfo "
+ "with size %d. Either this is an attack, or the "
+ "MAX_EXTRAINFO_UPLOAD_SIZE (%d) constant is too low.",
+ (int)ei->cache_info.signed_descriptor_len,
+ MAX_EXTRAINFO_UPLOAD_SIZE);
+ *msg = "Extrainfo document was too large";
+ extrainfo_free(ei);
+ return -1;
+ }
+
if ((r = routerinfo_incompatible_with_extrainfo(ri, ei, NULL, msg))) {
extrainfo_free(ei);
return r < 0 ? 0 : -1;
diff --git a/src/or/or.h b/src/or/or.h
index acbe2758e..d992d7cdc 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -141,6 +141,14 @@
* as an upload. */
#define MAX_DIR_UL_SIZE 500000
+/** Maximum size, in bytes, of a single router descriptor uploaded to us
+ * as a directory authority. Caches and clients fetch whatever descriptors
+ * the authorities tell them to fetch, and don't care about size. */
+#define MAX_DESCRIPTOR_UPLOAD_SIZE 20000
+
+/** Maximum size of a single extrainfo document, as above. */
+#define MAX_EXTRAINFO_UPLOAD_SIZE 50000
+
/** How long do we keep DNS cache entries before purging them (regardless of
* their TTL)? */
#define MAX_DNS_ENTRY_AGE (30*60)