summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changes/cid_4285
-rw-r--r--changes/cid_4505
-rw-r--r--changes/cov217_scanf5
-rw-r--r--changes/memleak_rendcache4
-rw-r--r--src/common/compat.c16
-rw-r--r--src/common/compat_libevent.c4
-rw-r--r--src/or/config.c2
-rw-r--r--src/or/connection.c8
-rw-r--r--src/or/directory.c6
-rw-r--r--src/or/dirserv.c2
-rw-r--r--src/or/eventdns.c4
-rw-r--r--src/or/geoip.c4
-rw-r--r--src/or/policies.c14
-rw-r--r--src/or/relay.c8
-rw-r--r--src/or/rendcommon.c1
-rw-r--r--src/or/routerlist.c2
-rw-r--r--src/or/routerparse.c8
-rw-r--r--src/test/test.c5
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();