diff options
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/buffers.c | 31 | ||||
-rw-r--r-- | src/or/config.c | 4 | ||||
-rw-r--r-- | src/or/connection_edge.c | 2 | ||||
-rw-r--r-- | src/or/rendcommon.c | 6 | ||||
-rw-r--r-- | src/or/rendservice.c | 18 | ||||
-rw-r--r-- | src/or/routerlist.c | 10 | ||||
-rw-r--r-- | src/or/routerparse.c | 6 |
7 files changed, 59 insertions, 18 deletions
diff --git a/src/or/buffers.c b/src/or/buffers.c index ab3346d9b7..e2e59eb680 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -75,12 +75,33 @@ typedef struct chunk_t { #define CHUNK_HEADER_LEN STRUCT_OFFSET(chunk_t, mem[0]) +/* We leave this many NUL bytes at the end of the buffer. */ +#define SENTINEL_LEN 4 + +/* Header size plus NUL bytes at the end */ +#define CHUNK_OVERHEAD (CHUNK_HEADER_LEN + SENTINEL_LEN) + /** Return the number of bytes needed to allocate a chunk to hold * <b>memlen</b> bytes. */ -#define CHUNK_ALLOC_SIZE(memlen) (CHUNK_HEADER_LEN + (memlen)) +#define CHUNK_ALLOC_SIZE(memlen) (CHUNK_OVERHEAD + (memlen)) /** Return the number of usable bytes in a chunk allocated with * malloc(<b>memlen</b>). */ -#define CHUNK_SIZE_WITH_ALLOC(memlen) ((memlen) - CHUNK_HEADER_LEN) +#define CHUNK_SIZE_WITH_ALLOC(memlen) ((memlen) - CHUNK_OVERHEAD) + +#define DEBUG_SENTINEL + +#ifdef DEBUG_SENTINEL +#define DBG_S(s) s +#else +#define DBG_S(s) (void)0 +#endif + +#define CHUNK_SET_SENTINEL(chunk, alloclen) do { \ + uint8_t *a = (uint8_t*) &(chunk)->mem[(chunk)->memlen]; \ + DBG_S(uint8_t *b = &((uint8_t*)(chunk))[(alloclen)-SENTINEL_LEN]); \ + DBG_S(tor_assert(a == b)); \ + memset(a,0,SENTINEL_LEN); \ + } while (0) /** Return the next character in <b>chunk</b> onto which data can be appended. * If the chunk is full, this might be off the end of chunk->mem. */ @@ -204,6 +225,7 @@ chunk_new_with_alloc_size(size_t alloc) ch->datalen = 0; ch->memlen = CHUNK_SIZE_WITH_ALLOC(alloc); ch->data = &ch->mem[0]; + CHUNK_SET_SENTINEL(ch, alloc); return ch; } #else @@ -221,6 +243,7 @@ chunk_new_with_alloc_size(size_t alloc) ch->datalen = 0; ch->memlen = CHUNK_SIZE_WITH_ALLOC(alloc); ch->data = &ch->mem[0]; + CHUNK_SET_SENTINEL(ch, alloc); return ch; } #endif @@ -231,11 +254,13 @@ static INLINE chunk_t * chunk_grow(chunk_t *chunk, size_t sz) { off_t offset; + const size_t new_alloc = CHUNK_ALLOC_SIZE(sz); tor_assert(sz > chunk->memlen); offset = chunk->data - chunk->mem; - chunk = tor_realloc(chunk, CHUNK_ALLOC_SIZE(sz)); + chunk = tor_realloc(chunk, new_alloc); chunk->memlen = sz; chunk->data = chunk->mem + offset; + CHUNK_SET_SENTINEL(chunk, new_alloc); return chunk; } diff --git a/src/or/config.c b/src/or/config.c index fde88ad680..709c5cc687 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -800,10 +800,8 @@ add_default_trusted_dir_authorities(dirinfo_type_t type) "v3ident=ED03BB616EB2F60BEC80151114BB25CEF515B226 " "131.188.40.189:80 F204 4413 DAC2 E02E 3D6B CF47 35A1 9BCA 1DE9 7281", "dannenberg orport=443 no-v2 " - "v3ident=585769C78764D58426B8B52B6651A5A71137189A " + "v3ident=0232AF901C31A04EE9848595AF9BB7620D4C5B2E " "193.23.244.244:80 7BE6 83E6 5D48 1413 21C5 ED92 F075 C553 64AC 7123", - "urras orport=80 no-v2 v3ident=80550987E1D626E3EBA5E5E75A458DE0626D088C " - "208.83.223.34:443 0AD3 FA88 4D18 F89E EA2D 89C0 1937 9E0E 7FD9 4417", "maatuska orport=80 no-v2 " "v3ident=49015F787433103580E3B66A1707A00E60F2D15B " "171.25.193.9:443 BD6A 8292 55CB 08E6 6FBE 7D37 4836 3586 E46B 3810", diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 895c0f7f01..39f8af61f6 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -748,7 +748,7 @@ connection_ap_fail_onehop(const char *failed_digest, /* we don't know the digest; have to compare addr:port */ tor_addr_t addr; if (!build_state || !build_state->chosen_exit || - !entry_conn->socks_request || !entry_conn->socks_request->address) + !entry_conn->socks_request) continue; if (tor_addr_parse(&addr, entry_conn->socks_request->address)<0 || !tor_addr_eq(&build_state->chosen_exit->addr, &addr) || diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index d1f8b1af99..296df55664 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -1327,8 +1327,10 @@ rend_cache_store_v2_desc_as_client(const char *desc, intro_size); if (n_intro_points <= 0) { log_warn(LD_REND, "Failed to parse introduction points. Either the " - "service has published a corrupt descriptor or you have " - "provided invalid authorization data."); + "service has published a corrupt descriptor, or you have " + "provided invalid authorization data, or (maybe!) the " + "server is deliberately serving broken data in an attempt " + "to crash you with bug 21018."); retval = -2; goto err; } else if (n_intro_points > MAX_INTRO_POINTS) { diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 436f2f4b69..0a54567393 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -939,11 +939,13 @@ rend_service_requires_uptime(rend_service_t *service) return 0; } -/** Check client authorization of a given <b>descriptor_cookie</b> for - * <b>service</b>. Return 1 for success and 0 for failure. */ +/** Check client authorization of a given <b>descriptor_cookie</b> of + * length <b>cookie_len</b> for <b>service</b>. Return 1 for success + * and 0 for failure. */ static int rend_check_authorization(rend_service_t *service, - const char *descriptor_cookie) + const char *descriptor_cookie, + size_t cookie_len) { rend_authorized_client_t *auth_client = NULL; tor_assert(service); @@ -954,6 +956,13 @@ rend_check_authorization(rend_service_t *service, return 0; } + if (cookie_len != REND_DESC_COOKIE_LEN) { + log_info(LD_REND, "Descriptor cookie is %lu bytes, but we expected " + "%lu bytes. Dropping cell.", + (unsigned long)cookie_len, (unsigned long)REND_DESC_COOKIE_LEN); + return 0; + } + /* Look up client authorization by descriptor cookie. */ SMARTLIST_FOREACH(service->clients, rend_authorized_client_t *, client, { if (tor_memeq(client->descriptor_cookie, descriptor_cookie, @@ -1300,7 +1309,8 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request, if (service->clients) { if (parsed_req->version == 3 && parsed_req->u.v3.auth_len > 0) { if (rend_check_authorization(service, - (const char*)parsed_req->u.v3.auth_data)) { + (const char*)parsed_req->u.v3.auth_data, + parsed_req->u.v3.auth_len)) { log_info(LD_REND, "Authorization data in INTRODUCE2 cell are valid."); } else { log_info(LD_REND, "The authorization data that are contained in " diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 8fe496b51e..9ad763c4d1 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -1537,8 +1537,14 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags) if ((type & MICRODESC_DIRINFO) && !is_trusted && !node->rs->version_supports_microdesc_cache) continue; - if (for_guard && node->using_as_guard) - continue; /* Don't make the same node a guard twice. */ + /* Don't make the same node a guard twice */ + if (for_guard && node->using_as_guard) { + continue; + } + /* Ensure that a directory guard is actually a guard node. */ + if (for_guard && !node->is_possible_guard) { + continue; + } if (try_excluding && routerset_contains_routerstatus(options->ExcludeNodes, status, country)) { diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 176c16f904..71373ce63e 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -3857,7 +3857,7 @@ get_next_token(memarea_t *area, if (tok->tp == ERR_) { /* No keyword matched; call it an "K_opt" or "A_unrecognized" */ - if (**s == '@') + if (*s < eol && **s == '@') tok->tp = A_UNKNOWN_; else tok->tp = K_OPT; @@ -4863,7 +4863,7 @@ rend_decrypt_introduction_points(char **ipos_decrypted, crypto_cipher_free(cipher); len = ipos_encrypted_size - 2 - client_entries_len - CIPHER_IV_LEN; - dec = tor_malloc(len); + dec = tor_malloc_zero(len + 1); declen = crypto_cipher_decrypt_with_iv(session_key, dec, len, ipos_encrypted + 2 + client_entries_len, ipos_encrypted_size - 2 - client_entries_len); @@ -4895,7 +4895,7 @@ rend_decrypt_introduction_points(char **ipos_decrypted, "small."); return -1; } - dec = tor_malloc_zero(ipos_encrypted_size - CIPHER_IV_LEN - 1); + dec = tor_malloc_zero(ipos_encrypted_size - CIPHER_IV_LEN - 1 + 1); declen = crypto_cipher_decrypt_with_iv(descriptor_cookie, dec, ipos_encrypted_size - |