Fix memory leaks in directory parsing

svn:r421
This commit is contained in:
Nick Mathewson 2003-08-28 04:21:57 +00:00
parent c8401a30ae
commit e14aedaad0
2 changed files with 32 additions and 4 deletions

View File

@ -150,6 +150,8 @@ void routerinfo_free(routerinfo_t *router)
free(router->address); free(router->address);
if (router->pkey) if (router->pkey)
crypto_free_pk_env(router->pkey); crypto_free_pk_env(router->pkey);
if (router->signing_pkey)
crypto_free_pk_env(router->signing_pkey);
e = router->exit_policy; e = router->exit_policy;
while (e) { while (e) {
etmp = e->next; etmp = e->next;
@ -285,6 +287,25 @@ struct directory_token {
} val; } val;
}; };
/* Free any malloced resources allocated for a token. Don't call this if
you inherit the reference to those resources.
*/
static void
router_release_token(directory_token_t *tok)
{
switch (tok->tp)
{
case _SIGNATURE:
free(tok->val.signature);
break;
case _PUBLIC_KEY:
crypto_free_pk_env(tok->val.public_key);
break;
default:
break;
}
}
static int static int
_router_get_next_token(char **s, directory_token_t *tok) { _router_get_next_token(char **s, directory_token_t *tok) {
char *next; char *next;
@ -568,6 +589,7 @@ int router_get_dir_from_string_impl(char *s, directory_t **dest,
#define TOK_IS(type,name) \ #define TOK_IS(type,name) \
do { \ do { \
if (tok.tp != type) { \ if (tok.tp != type) { \
router_release_token(&tok); \
log(LOG_ERR, "Error reading directory: expected %s", name); \ log(LOG_ERR, "Error reading directory: expected %s", name); \
return -1; \ return -1; \
} } while(0) } } while(0)
@ -711,8 +733,10 @@ routerinfo_t *router_get_entry_from_string(char **s) {
routerinfo_t *router; routerinfo_t *router;
if (router_get_next_token(s, &tok)) return NULL; if (router_get_next_token(s, &tok)) return NULL;
router = router_get_entry_from_string_tok(s, &tok); router = router_get_entry_from_string_tok(s, &tok);
if (tok.tp != _EOF) if (tok.tp != _EOF) {
router_release_token(&tok);
return NULL; return NULL;
}
return router; return router;
} }
@ -732,6 +756,7 @@ static routerinfo_t *router_get_entry_from_string_tok(char**s, directory_token_t
#define ARGS tok->val.cmd.args #define ARGS tok->val.cmd.args
if (tok->tp != K_ROUTER) { if (tok->tp != K_ROUTER) {
router_release_token(tok);
log(LOG_ERR,"router_get_entry_from_string(): Entry does not start with \"router\""); log(LOG_ERR,"router_get_entry_from_string(): Entry does not start with \"router\"");
return NULL; return NULL;
} }
@ -775,7 +800,7 @@ static routerinfo_t *router_get_entry_from_string_tok(char**s, directory_token_t
router->or_port, router->ap_port, router->dir_port, router->bandwidth); router->or_port, router->ap_port, router->dir_port, router->bandwidth);
NEXT_TOKEN(); NEXT_TOKEN();
if (tok->tp != _PUBLIC_KEY) { if (tok->tp != _PUBLIC_KEY) {
log(LOG_ERR,"router_get_entry_from_string(): Missing public key"); log(LOG_ERR,"router_get_entry_from_string(): Missing public key");
goto err; goto err;
} /* Check key length */ } /* Check key length */
@ -800,10 +825,13 @@ static routerinfo_t *router_get_entry_from_string_tok(char**s, directory_token_t
return router; return router;
err: err:
router_release_token(tok);
if(router->address) if(router->address)
free(router->address); free(router->address);
if(router->pkey) if(router->pkey)
crypto_free_pk_env(router->pkey); crypto_free_pk_env(router->pkey);
if(router->signing_pkey)
crypto_free_pk_env(router->signing_pkey);
router_free_exit_policy(router); router_free_exit_policy(router);
free(router); free(router);
return NULL; return NULL;

View File

@ -539,7 +539,7 @@ test_dir_format()
&pk1_str_len)); &pk1_str_len));
test_assert(!crypto_pk_write_public_key_to_string(pk2 , &pk2_str, test_assert(!crypto_pk_write_public_key_to_string(pk2 , &pk2_str,
&pk2_str_len)); &pk2_str_len));
strcpy(buf2, "router testaddr1.foo.bar 9000 9001 9002 9003 1000\n"); strcpy(buf2, "router testaddr1.foo.bar 9000 9002 9003 1000\n");
strcat(buf2, pk1_str); strcat(buf2, pk1_str);
strcat(buf2, "\n"); strcat(buf2, "\n");
@ -559,7 +559,7 @@ test_dir_format()
test_assert(rp1->signing_pkey == NULL); test_assert(rp1->signing_pkey == NULL);
test_assert(rp1->exit_policy == NULL); test_assert(rp1->exit_policy == NULL);
strcpy(buf2, "router tor.tor.tor 9005 0 0 0 3000\n"); strcpy(buf2, "router tor.tor.tor 9005 0 0 3000\n");
strcat(buf2, pk2_str); strcat(buf2, pk2_str);
strcat(buf2, "signing-key\n"); strcat(buf2, "signing-key\n");
strcat(buf2, pk1_str); strcat(buf2, pk1_str);