diff options
-rw-r--r-- | changes/cid_428 | 5 | ||||
-rw-r--r-- | changes/cid_450 | 5 | ||||
-rw-r--r-- | changes/cov217_scanf | 5 | ||||
-rw-r--r-- | changes/memleak_rendcache | 4 | ||||
-rw-r--r-- | src/common/compat.c | 16 | ||||
-rw-r--r-- | src/common/compat_libevent.c | 4 | ||||
-rw-r--r-- | src/or/config.c | 2 | ||||
-rw-r--r-- | src/or/connection.c | 8 | ||||
-rw-r--r-- | src/or/directory.c | 6 | ||||
-rw-r--r-- | src/or/dirserv.c | 2 | ||||
-rw-r--r-- | src/or/eventdns.c | 4 | ||||
-rw-r--r-- | src/or/geoip.c | 4 | ||||
-rw-r--r-- | src/or/policies.c | 14 | ||||
-rw-r--r-- | src/or/relay.c | 8 | ||||
-rw-r--r-- | src/or/rendcommon.c | 1 | ||||
-rw-r--r-- | src/or/routerlist.c | 2 | ||||
-rw-r--r-- | src/or/routerparse.c | 8 | ||||
-rw-r--r-- | src/test/test.c | 5 |
18 files changed, 73 insertions, 30 deletions
diff --git a/changes/cid_428 b/changes/cid_428 new file mode 100644 index 0000000000..cb0fc8c2b2 --- /dev/null +++ b/changes/cid_428 @@ -0,0 +1,5 @@ + o Minor bugfixes: + - Always NUL-terminate the sun_path field of a sockaddr_un before + passing it to the kernel. (Not a security issue: kernels are + smart enough to reject bad sockaddr_uns.) Found by Coverity; CID + # 428. Bugfix on Tor 0.2.0.3-alpha. diff --git a/changes/cid_450 b/changes/cid_450 new file mode 100644 index 0000000000..2045fca239 --- /dev/null +++ b/changes/cid_450 @@ -0,0 +1,5 @@ + o Minor bugfixes: + - Don't stack-allocate the list of supplementary GIDs when we're + about to log them. Stack-allocating NGROUPS_MAX gid_t elements + could take up to 256K, which is way too much stack. Found by + Coverity; CID #450. Bugfix on 0.2.1.7-alpha. diff --git a/changes/cov217_scanf b/changes/cov217_scanf new file mode 100644 index 0000000000..368bca825e --- /dev/null +++ b/changes/cov217_scanf @@ -0,0 +1,5 @@ + o Code simplification and refactoring: + - Use tor_sscanf in place of scanf in more places through the + code. This makes us a little more locale-independent, and + should help shut up code-analysis tools that can't tell + a safe sscanf string from a dangerous one. diff --git a/changes/memleak_rendcache b/changes/memleak_rendcache new file mode 100644 index 0000000000..93b1f6141b --- /dev/null +++ b/changes/memleak_rendcache @@ -0,0 +1,4 @@ + o Minor bugfixes: + - Fix a memory leak when receiving a descriptor for a hidden + service we didn't ask for. Found by Coverity; CID#30. Bugfix on + 0.2.2.26-beta. diff --git a/src/common/compat.c b/src/common/compat.c index 83cf0322d9..330c432284 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -1280,7 +1280,8 @@ log_credential_status(void) /* Read, effective and saved GIDs */ gid_t rgid, egid, sgid; /* Supplementary groups */ - gid_t sup_gids[NGROUPS_MAX + 1]; + gid_t *sup_gids = NULL; + int sup_gids_size; /* Number of supplementary groups */ int ngids; @@ -1326,9 +1327,19 @@ log_credential_status(void) #endif /* log supplementary groups */ - if ((ngids = getgroups(NGROUPS_MAX + 1, sup_gids)) < 0) { + sup_gids_size = 64; + sup_gids = tor_malloc(sizeof(gid_t) * 64); + while ((ngids = getgroups(sup_gids_size, sup_gids)) < 0 && + errno == EINVAL && + sup_gids_size < NGROUPS_MAX) { + sup_gids_size *= 2; + sup_gids = tor_realloc(sup_gids, sizeof(gid_t) * sup_gids_size); + } + + if (ngids < 0) { log_warn(LD_GENERAL, "Error getting supplementary GIDs: %s", strerror(errno)); + tor_free(sup_gids); return -1; } else { int i, retval = 0; @@ -1358,6 +1369,7 @@ log_credential_status(void) tor_free(cp); }); smartlist_free(elts); + tor_free(sup_gids); return retval; } diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c index e0c7e3a2da..c338dd6c05 100644 --- a/src/common/compat_libevent.c +++ b/src/common/compat_libevent.c @@ -264,7 +264,7 @@ tor_decode_libevent_version(const char *v) /* Try the new preferred "1.4.11-stable" format. * Also accept "1.4.14b-stable". */ - fields = sscanf(v, "%u.%u.%u%c%c", &major, &minor, &patchlevel, &c, &e); + fields = tor_sscanf(v, "%u.%u.%u%c%c", &major, &minor, &patchlevel, &c, &e); if (fields == 3 || ((fields == 4 || fields == 5 ) && (c == '-' || c == '_')) || (fields == 5 && TOR_ISALPHA(c) && (e == '-' || e == '_'))) { @@ -272,7 +272,7 @@ tor_decode_libevent_version(const char *v) } /* Try the old "1.3e" format. */ - fields = sscanf(v, "%u.%u%c%c", &major, &minor, &c, &extra); + fields = tor_sscanf(v, "%u.%u%c%c", &major, &minor, &c, &extra); if (fields == 3 && TOR_ISALPHA(c)) { return V_OLD(major, minor, c); } else if (fields == 2) { diff --git a/src/or/config.c b/src/or/config.c index df5cc86578..bb335dd5f1 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -2367,7 +2367,7 @@ options_trial_assign(config_line_t *list, int use_defaults, * Called from option_reset() and config_free(). */ static void option_clear(const config_format_t *fmt, or_options_t *options, - const const config_var_t *var) + const config_var_t *var) { void *lvalue = STRUCT_VAR_P(options, var->var_offset); (void)fmt; /* unused */ diff --git a/src/or/connection.c b/src/or/connection.c index ec43577dfa..e8969e09fc 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -854,7 +854,13 @@ create_unix_sockaddr(const char *listenaddress, char **readable_address, sockaddr = tor_malloc_zero(sizeof(struct sockaddr_un)); sockaddr->sun_family = AF_UNIX; - strncpy(sockaddr->sun_path, listenaddress, sizeof(sockaddr->sun_path)); + if (strlcpy(sockaddr->sun_path, listenaddress, sizeof(sockaddr->sun_path)) + >= sizeof(sockaddr->sun_path)) { + log_warn(LD_CONFIG, "Unix socket path '%s' is too long to fit.", + escaped(listenaddress)); + tor_free(sockaddr); + return NULL; + } if (readable_address) *readable_address = tor_strdup(listenaddress); diff --git a/src/or/directory.c b/src/or/directory.c index 7ded115274..9e1373d46f 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -2592,7 +2592,7 @@ client_likes_consensus(networkstatus_t *v, const char *want_url) * Always return 0. */ static int directory_handle_command_get(dir_connection_t *conn, const char *headers, - const char *body, size_t body_len) + const char *req_body, size_t req_body_len) { size_t dlen; char *url, *url_mem, *header; @@ -2602,8 +2602,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers, size_t url_len; /* We ignore the body of a GET request. */ - (void)body; - (void)body_len; + (void)req_body; + (void)req_body_len; log_debug(LD_DIRSERV,"Received GET command."); diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 33796fc2de..0ea1ef6489 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -2440,7 +2440,7 @@ measured_bw_line_parse(measured_bw_line_t *out, const char *orig_line) tor_free(line); return -1; } - strncpy(out->node_hex, cp, sizeof(out->node_hex)); + strlcpy(out->node_hex, cp, sizeof(out->node_hex)); got_node_id=1; } } while ((cp = tor_strtok_r(NULL, " \t", &strtok_state))); diff --git a/src/or/eventdns.c b/src/or/eventdns.c index 321b7d753f..7fe376baff 100644 --- a/src/or/eventdns.c +++ b/src/or/eventdns.c @@ -1831,8 +1831,8 @@ evdns_server_request_respond(struct evdns_server_request *_req, int err) r = sendto(port->socket, req->response, req->response_len, 0, (struct sockaddr*) &req->addr, req->addrlen); if (r<0) { - int err = last_error(port->socket); - if (! error_is_eagain(err)) + int error = last_error(port->socket); + if (! error_is_eagain(error)) return -1; if (port->pending_replies) { diff --git a/src/or/geoip.c b/src/or/geoip.c index 59490bdaf8..62c7a5c394 100644 --- a/src/or/geoip.c +++ b/src/or/geoip.c @@ -116,10 +116,10 @@ geoip_parse_entry(const char *line) ++line; if (*line == '#') return 0; - if (sscanf(line,"%u,%u,%2s", &low, &high, b) == 3) { + if (tor_sscanf(line,"%u,%u,%2s", &low, &high, b) == 3) { geoip_add_entry(low, high, b); return 0; - } else if (sscanf(line,"\"%u\",\"%u\",\"%2s\",", &low, &high, b) == 3) { + } else if (tor_sscanf(line,"\"%u\",\"%u\",\"%2s\",", &low, &high, b) == 3) { geoip_add_entry(low, high, b); return 0; } else { diff --git a/src/or/policies.c b/src/or/policies.c index 983df8696e..1b5408c777 100644 --- a/src/or/policies.c +++ b/src/or/policies.c @@ -83,15 +83,15 @@ policy_expand_private(smartlist_t **policy) continue; } for (i = 0; private_nets[i]; ++i) { - addr_policy_t policy; - memcpy(&policy, p, sizeof(addr_policy_t)); - policy.is_private = 0; - policy.is_canonical = 0; - if (tor_addr_parse_mask_ports(private_nets[i], &policy.addr, - &policy.maskbits, &port_min, &port_max)<0) { + addr_policy_t newpolicy; + memcpy(&newpolicy, p, sizeof(addr_policy_t)); + newpolicy.is_private = 0; + newpolicy.is_canonical = 0; + if (tor_addr_parse_mask_ports(private_nets[i], &newpolicy.addr, + &newpolicy.maskbits, &port_min, &port_max)<0) { tor_assert(0); } - smartlist_add(tmp, addr_policy_get_canonical_entry(&policy)); + smartlist_add(tmp, addr_policy_get_canonical_entry(&newpolicy)); } addr_policy_free(p); }); diff --git a/src/or/relay.c b/src/or/relay.c index d647b18a81..df6d0a8a5f 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -2337,13 +2337,13 @@ connection_or_flush_from_first_active_circuit(or_connection_t *conn, int max, /* Calculate the exact time that this cell has spent in the queue. */ if (get_options()->CellStatistics && !CIRCUIT_IS_ORIGIN(circ)) { - struct timeval now; + struct timeval tvnow; uint32_t flushed; uint32_t cell_waiting_time; insertion_time_queue_t *it_queue = queue->insertion_times; - tor_gettimeofday_cached(&now); - flushed = (uint32_t)((now.tv_sec % SECONDS_IN_A_DAY) * 100L + - (uint32_t)now.tv_usec / (uint32_t)10000L); + tor_gettimeofday_cached(&tvnow); + flushed = (uint32_t)((tvnow.tv_sec % SECONDS_IN_A_DAY) * 100L + + (uint32_t)tvnow.tv_usec / (uint32_t)10000L); if (!it_queue || !it_queue->first) { log_info(LD_GENERAL, "Cannot determine insertion time of cell. " "Looks like the CellStatistics option was " diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index e81510a9cd..94bb002210 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -1040,6 +1040,7 @@ rend_cache_store(const char *desc, size_t desc_len, int published, log_warn(LD_REND, "Received service descriptor for service ID %s; " "expected descriptor for service ID %s.", query, safe_str(service_id)); + rend_service_descriptor_free(parsed); return -2; } now = time(NULL); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index f711282b13..15f643cf79 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -2274,6 +2274,8 @@ hex_digest_nickname_matches(const char *hexdigest, const char *identity_digest, return 0; if (nn_char == '=' || nn_char == '~') { + if (!nickname) + return 0; if (strcasecmp(nn_buf, nickname)) return 0; if (nn_char == '=' && !is_named) diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 67b238e747..d1b2cd0fb7 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -3512,10 +3512,10 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos) siglist = detached_get_signatures(sigs, flavor); is_duplicate = 0; - SMARTLIST_FOREACH(siglist, document_signature_t *, s, { - if (s->alg == alg && - tor_memeq(id_digest, s->identity_digest, DIGEST_LEN) && - tor_memeq(sk_digest, s->signing_key_digest, DIGEST_LEN)) { + SMARTLIST_FOREACH(siglist, document_signature_t *, dsig, { + if (dsig->alg == alg && + tor_memeq(id_digest, dsig->identity_digest, DIGEST_LEN) && + tor_memeq(sk_digest, dsig->signing_key_digest, DIGEST_LEN)) { is_duplicate = 1; } }); diff --git a/src/test/test.c b/src/test/test.c index 1db1546639..02d238e26d 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -1318,7 +1318,10 @@ main(int c, const char **v) } options->command = CMD_RUN_UNITTESTS; - crypto_global_init(0, NULL, NULL); + if (crypto_global_init(0, NULL, NULL)) { + printf("Can't initialize crypto subsystem; exiting.\n"); + return 1; + } rep_hist_init(); network_init(); setup_directory(); |