Commit e14aedaa authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Fix memory leaks in directory parsing


svn:r421
parent c8401a30
Loading
Loading
Loading
Loading
+30 −2
Original line number Diff line number Diff line
@@ -150,6 +150,8 @@ void routerinfo_free(routerinfo_t *router)
    free(router->address);
  if (router->pkey)
    crypto_free_pk_env(router->pkey);
  if (router->signing_pkey)
    crypto_free_pk_env(router->signing_pkey);
  e = router->exit_policy;
  while (e) {
    etmp = e->next;
@@ -285,6 +287,25 @@ struct directory_token {
  } 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
_router_get_next_token(char **s, directory_token_t *tok) {
  char *next;
@@ -568,6 +589,7 @@ int router_get_dir_from_string_impl(char *s, directory_t **dest,
#define TOK_IS(type,name)                                               \
  do {                                                                  \
    if (tok.tp != type) {                                               \
      router_release_token(&tok);                                       \
      log(LOG_ERR, "Error reading directory: expected %s", name);       \
      return -1;                                                        \
    } } while(0)
@@ -711,8 +733,10 @@ routerinfo_t *router_get_entry_from_string(char **s) {
  routerinfo_t *router;
  if (router_get_next_token(s, &tok)) return NULL;
  router = router_get_entry_from_string_tok(s, &tok);
  if (tok.tp != _EOF)
  if (tok.tp != _EOF) {
    router_release_token(&tok);
    return NULL;
  }
  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

  if (tok->tp != K_ROUTER) {
    router_release_token(tok);
    log(LOG_ERR,"router_get_entry_from_string(): Entry does not start with \"router\"");
    return NULL;
  }
@@ -800,10 +825,13 @@ static routerinfo_t *router_get_entry_from_string_tok(char**s, directory_token_t
  return router;

 err:
  router_release_token(tok); 
  if(router->address)
    free(router->address);
  if(router->pkey)
    crypto_free_pk_env(router->pkey);
  if(router->signing_pkey)
    crypto_free_pk_env(router->signing_pkey);
  router_free_exit_policy(router);
  free(router);
  return NULL;
+2 −2
Original line number Diff line number Diff line
@@ -539,7 +539,7 @@ test_dir_format()
                                                    &pk1_str_len));
  test_assert(!crypto_pk_write_public_key_to_string(pk2 , &pk2_str, 
                                                    &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, "\n");
  
@@ -559,7 +559,7 @@ test_dir_format()
  test_assert(rp1->signing_pkey == 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, "signing-key\n");
  strcat(buf2, pk1_str);