Fix some hard to trigger but nonetheless real memory leaks spotted by an anonymous contributor. Needs review. Partial backport candidate.
svn:r13147
but client versions are not.
- Fix rare bug on REDIRECTSTREAM control command when called with no
port set: it could erroneously report an error when none had happened.
+ - Avoid bogus crash-prone, leak-prone tor_realloc when we're compressing
+ large objects and find ourselves with more than 4k left over. Bugfix
+ on 0.2.0.
+ - Fix a small memory leak when setting up a hidden service.
+ - Fix a few memory leaks that could in theory happen under bizarre error
+ conditions.
o Minor features (controller):
- Get NS events working again. (Patch from tup)
*out_len = stream->total_out;
if (stream->total_out > out_size + 4097) {
/* If we're wasting more than 4k, don't. */
- tor_realloc(*out, stream->total_out + 1);
+ *out = tor_realloc(*out, stream->total_out + 1);
}
if (deflateEnd(stream)!=Z_OK) {
log_warn(LD_BUG, "Error freeing gzip structures");
#include <string.h>
// #define V2_HANDSHAKE_SERVER
-// #define V2_HANDSHAKE_CLIENT
+#define V2_HANDSHAKE_CLIENT
/* Copied from or.h */
#define LEGAL_NICKNAME_CHARACTERS \
if (parse_redirect_line(sl, cl, &errmsg)<0) {
log_warn(LD_CONFIG, "%s", errmsg);
tor_free(errmsg);
+ SMARTLIST_FOREACH(sl, exit_redirect_t *, er, tor_free(er));
+ smartlist_free(sl);
return -1;
}
}
smartlist_clear(lines);
}
}
+ smartlist_free(lines);
}
/** Last value actually set by resolve_my_address. */
connection_write_str_to_buf("551 Couldn't parse string\r\n", conn);
SMARTLIST_FOREACH(entries, char *, cp, tor_free(cp));
smartlist_free(entries);
+ tor_free(key);
return 0;
}
}
res = dirserv_get_routerdescs(descs, url, &msg);
if (res) {
log_warn(LD_CONTROL, "getinfo '%s': %s", question, msg);
+ smartlist_free(descs);
return -1;
}
SMARTLIST_FOREACH(descs, signed_descriptor_t *, sd,
time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
char *answer;
routerlist_t *rl = router_get_routerlist();
- smartlist_t *statuses = smartlist_create();
+ smartlist_t *statuses;
uint8_t purpose = router_purpose_from_string(purpose_string);
routerstatus_t rs;
int bridge_auth = authdir_mode_bridge(get_options());
return NULL;
}
+ statuses = smartlist_create();
SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
if (ri->cache_info.published_on < cutoff)
continue;
len = crypto_dh_compute_secret(handshake_state, handshake_reply, DH_KEY_LEN,
key_material, 20+key_out_len);
if (len < 0)
- return -1;
+ goto err;
if (memcmp(key_material, handshake_reply+DH_KEY_LEN, 20)) {
/* H(K) does *not* match. Something fishy. */
- tor_free(key_material);
log_warn(LD_PROTOCOL,"Digest DOES NOT MATCH on onion handshake. "
"Bug or attack.");
- return -1;
+ goto err;
}
/* use the rest of the key material for our shared keys, digests, etc */
tor_free(key_material);
return 0;
+ err:
+ tor_free(key_material);
+ return -1;
}
/** Implement the server side of the CREATE_FAST abbreviated handshake. The
/* H(K) does *not* match. Something fishy. */
log_warn(LD_PROTOCOL,"Digest DOES NOT MATCH on fast handshake. "
"Bug or attack.");
+ tor_free(out);
return -1;
}
memcpy(key_out, out+DIGEST_LEN, key_out_len);
log_warn(LD_CONFIG,
"Got multiple HiddenServiceNodes lines for a single "
"service.");
+ rend_service_free(service);
return -1;
}
service->intro_prefer_nodes = tor_strdup(line->value);
log_warn(LD_CONFIG,
"Got multiple HiddenServiceExcludedNodes lines for "
"a single service.");
+ rend_service_free(service);
return -1;
}
service->intro_exclude_nodes = tor_strdup(line->value);
if (strlen(version_str) != 1 || strspn(version_str, "02") != 1) {
log_warn(LD_CONFIG,
"HiddenServiceVersion can only be 0 and/or 2.");
+ SMARTLIST_FOREACH(versions, char *, cp, tor_free(cp));
+ smartlist_free(versions);
+ rend_service_free(service);
return -1;
}
version = atoi(version_str);
* value; otherwise leave it at -1. */
if (versions_bitmask == 1 << 0) service->descriptor_version = 0;
if (versions_bitmask == 1 << 2) service->descriptor_version = 2;
+ SMARTLIST_FOREACH(versions, char *, cp, tor_free(cp));
+ smartlist_free(versions);
}
}
if (service) {
if (len != REND_COOKIE_LEN+DH_KEY_LEN) {
log_warn(LD_PROTOCOL, "Bad length %u for INTRODUCE2 cell.", (int)len);
reason = END_CIRC_REASON_TORPROTOCOL;
- return -1;
+ goto err;
}
r_cookie = ptr;
if (!server_mode(options)) {
if (!(prkey = crypto_new_pk_env()))
return -1;
- if (crypto_pk_generate_key(prkey))
+ if (crypto_pk_generate_key(prkey)) {
+ crypto_free_pk_env(prkey);
return -1;
+ }
set_identity_key(prkey);
/* Create a TLS context; default the client nickname to "client". */
if (tor_tls_context_new(get_identity_key(),
if (extrainfo_dump_to_string(ei->cache_info.signed_descriptor_body, 8192,
ei, get_identity_key()) < 0) {
log_warn(LD_BUG, "Couldn't generate extra-info descriptor.");
+ extrainfo_free(ei);
return -1;
}
ei->cache_info.signed_descriptor_len =
int fascistfirewall = ! (flags & PDS_IGNORE_FASCISTFIREWALL);
int prefer_tunnel = (flags & _PDS_PREFER_TUNNELED_DIR_CONNS);
+ if (!trusted_dir_servers)
+ return NULL;
+
direct = smartlist_create();
tunnel = smartlist_create();
overloaded_direct = smartlist_create();
overloaded_tunnel = smartlist_create();
- if (!trusted_dir_servers)
- return NULL;
-
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, d,
{
int is_overloaded =
tor_assert(r);
if (!with_annotations) {
if (memcmp("router ", r, 7) && memcmp("extra-info ", r, 11)) {
+ char *cp = tor_strndup(r, 64);
log_err(LD_DIR, "descriptor at %p begins with unexpected string %s",
- desc, tor_strndup(r, 64));
+ desc, escaped(cp));
+ tor_free(cp);
}
tor_assert(!memcmp("router ", r, 7) || !memcmp("extra-info ", r, 11));
}
}
if (tok->tp != K_DIR_SIGNING_KEY) {
log_warn(LD_DIR, "Dir-signing-key token did not parse as expected");
- return NULL;
+ goto done;
}
if (tok->key) {
tok->key = NULL; /* steal reference. */
} else {
log_warn(LD_DIR, "Dir-signing-key token contained no key");
- return NULL;
}
- token_free(tok);
+ done:
+ if (tok) token_free(tok);
return key;
}
if (router_get_router_hash(s, digest) < 0) {
log_warn(LD_DIR, "Couldn't compute router hash.");
- return NULL;
+ goto err;
}
{
int flags = 0;
"dir-key-certification\n",
address?"\ndir-address ":"", address?address:"",
fingerprint, published, expires, ident, signing);
+ tor_free(ident);
+ tor_free(signing);
signed_len = strlen(buf);
SHA1((const unsigned char*)buf,signed_len,(unsigned char*)digest);
if ((len = build_socks_resolve_request(&req, "", hostname, reverse,
version))<0) {
log_err(LD_BUG,"Error generating SOCKS request");
+ tor_assert(!req);
return -1;
}
if (write_all(s, req, len, 1) != len) {