diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-05-22 12:27:15 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-05-22 12:27:15 -0400 |
commit | a3a8d80bebdbb8988a2f33dea8b18a41e445c06f (patch) | |
tree | 9ce3e1b62be136f2b5e886a7013e2f58c58b75b9 /src/or | |
parent | 3d126632430fe60e7ced72bf82cd2c16f297297e (diff) | |
parent | d2bc019053058b09b5552d327106d9fbe0acad56 (diff) | |
download | tor-a3a8d80bebdbb8988a2f33dea8b18a41e445c06f.tar.gz tor-a3a8d80bebdbb8988a2f33dea8b18a41e445c06f.zip |
Merge branch 'trove-2018-005_032' into trove-2018-005_033
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/dirserv.c | 6 | ||||
-rw-r--r-- | src/or/protover.c | 34 | ||||
-rw-r--r-- | src/or/protover.h | 3 |
3 files changed, 42 insertions, 1 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 1c1610ff93..2a8da6a10a 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -2963,6 +2963,12 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, microdescriptors = smartlist_new(); SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) { + /* If it has a protover list and contains a protocol name greater than + * MAX_PROTOCOL_NAME_LENGTH, skip it. */ + if (ri->protocol_list && + protover_contains_long_protocol_names(ri->protocol_list)) { + continue; + } if (ri->cache_info.published_on >= cutoff) { routerstatus_t *rs; vote_routerstatus_t *vrs; diff --git a/src/or/protover.c b/src/or/protover.c index 6532f09c2f..811f91410f 100644 --- a/src/or/protover.c +++ b/src/or/protover.c @@ -53,6 +53,11 @@ static const struct { #define N_PROTOCOL_NAMES ARRAY_LENGTH(PROTOCOL_NAMES) +/* Maximum allowed length of any single subprotocol name. */ +// C_RUST_COUPLED: src/rust/protover/protover.rs +// `MAX_PROTOCOL_NAME_LENGTH` +static const uint MAX_PROTOCOL_NAME_LENGTH = 100; + /** * Given a protocol_type_t, return the corresponding string used in * descriptors. @@ -198,6 +203,15 @@ parse_single_entry(const char *s, const char *end_of_entry) if (equals == s) goto error; + /* The name must not be longer than MAX_PROTOCOL_NAME_LENGTH. */ + if (equals - s > MAX_PROTOCOL_NAME_LENGTH) { + log_warn(LD_NET, "When parsing a protocol entry, I got a very large " + "protocol name. This is possibly an attack or a bug, unless " + "the Tor network truly supports protocol names larger than " + "%ud characters. The offending string was: %s", + MAX_PROTOCOL_NAME_LENGTH, escaped(out->name)); + goto error; + } out->name = tor_strndup(s, equals-s); tor_assert(equals < end_of_entry); @@ -263,6 +277,18 @@ parse_protocol_list(const char *s) } /** + * Return true if the unparsed protover in <b>s</b> would contain a protocol + * name longer than MAX_PROTOCOL_NAME_LENGTH, and false otherwise. + */ +bool +protover_contains_long_protocol_names(const char *s) +{ + if (!parse_protocol_list(s)) + return true; + return false; +} + +/** * Given a protocol type and version number, return true iff we know * how to speak that protocol. */ @@ -439,6 +465,14 @@ expand_protocol_list(const smartlist_t *protos) SMARTLIST_FOREACH_BEGIN(protos, const proto_entry_t *, ent) { const char *name = ent->name; + if (strlen(name) > MAX_PROTOCOL_NAME_LENGTH) { + log_warn(LD_NET, "When expanding a protocol entry, I got a very large " + "protocol name. This is possibly an attack or a bug, unless " + "the Tor network truly supports protocol names larger than " + "%ud characters. The offending string was: %s", + MAX_PROTOCOL_NAME_LENGTH, escaped(name)); + continue; + } SMARTLIST_FOREACH_BEGIN(ent->ranges, const proto_range_t *, range) { uint32_t u; for (u = range->low; u <= range->high; ++u) { diff --git a/src/or/protover.h b/src/or/protover.h index 477274e293..b94ebab15b 100644 --- a/src/or/protover.h +++ b/src/or/protover.h @@ -10,7 +10,7 @@ #define TOR_PROTOVER_H #include "container.h" - +#include <stdbool.h> /** The first version of Tor that included "proto" entries in its * descriptors. Authorities should use this to decide whether to * guess proto lines. */ @@ -42,6 +42,7 @@ typedef enum protocol_type_t { PRT_CONS, } protocol_type_t; +bool protover_contains_long_protocol_names(const char *s); int protover_all_supported(const char *s, char **missing); int protover_is_supported_here(protocol_type_t pr, uint32_t ver); const char *protover_get_supported_protocols(void); |