[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r13147: Fix some hard to trigger but nonetheless real memory leaks s (in tor/trunk: . src/common src/or src/tools)



Author: nickm
Date: 2008-01-16 00:27:19 -0500 (Wed, 16 Jan 2008)
New Revision: 13147

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/src/common/torgzip.c
   tor/trunk/src/common/tortls.c
   tor/trunk/src/or/config.c
   tor/trunk/src/or/control.c
   tor/trunk/src/or/networkstatus.c
   tor/trunk/src/or/onion.c
   tor/trunk/src/or/rendservice.c
   tor/trunk/src/or/router.c
   tor/trunk/src/or/routerlist.c
   tor/trunk/src/or/routerparse.c
   tor/trunk/src/tools/tor-gencert.c
   tor/trunk/src/tools/tor-resolve.c
Log:
 r17639@catbus:  nickm | 2008-01-15 19:09:21 -0500
 Fix some hard to trigger but nonetheless real memory leaks spotted by an anonymous contributor.  Needs review.  Partial backport candidate.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r17639] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2008-01-16 04:15:41 UTC (rev 13146)
+++ tor/trunk/ChangeLog	2008-01-16 05:27:19 UTC (rev 13147)
@@ -58,6 +58,12 @@
       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)

Modified: tor/trunk/src/common/torgzip.c
===================================================================
--- tor/trunk/src/common/torgzip.c	2008-01-16 04:15:41 UTC (rev 13146)
+++ tor/trunk/src/common/torgzip.c	2008-01-16 05:27:19 UTC (rev 13147)
@@ -139,7 +139,7 @@
   *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");

Modified: tor/trunk/src/common/tortls.c
===================================================================
--- tor/trunk/src/common/tortls.c	2008-01-16 04:15:41 UTC (rev 13146)
+++ tor/trunk/src/common/tortls.c	2008-01-16 05:27:19 UTC (rev 13147)
@@ -43,7 +43,7 @@
 #include <string.h>
 
 // #define V2_HANDSHAKE_SERVER
-// #define V2_HANDSHAKE_CLIENT
+#define V2_HANDSHAKE_CLIENT
 
 /* Copied from or.h */
 #define LEGAL_NICKNAME_CHARACTERS \

Modified: tor/trunk/src/or/config.c
===================================================================
--- tor/trunk/src/or/config.c	2008-01-16 04:15:41 UTC (rev 13146)
+++ tor/trunk/src/or/config.c	2008-01-16 05:27:19 UTC (rev 13147)
@@ -1153,6 +1153,8 @@
       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;
       }
     }
@@ -2096,6 +2098,7 @@
       smartlist_clear(lines);
     }
   }
+  smartlist_free(lines);
 }
 
 /** Last value actually set by resolve_my_address. */

Modified: tor/trunk/src/or/control.c
===================================================================
--- tor/trunk/src/or/control.c	2008-01-16 04:15:41 UTC (rev 13146)
+++ tor/trunk/src/or/control.c	2008-01-16 05:27:19 UTC (rev 13147)
@@ -704,6 +704,7 @@
           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;
         }
       }
@@ -1440,6 +1441,7 @@
     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,

Modified: tor/trunk/src/or/networkstatus.c
===================================================================
--- tor/trunk/src/or/networkstatus.c	2008-01-16 04:15:41 UTC (rev 13146)
+++ tor/trunk/src/or/networkstatus.c	2008-01-16 05:27:19 UTC (rev 13147)
@@ -1796,7 +1796,7 @@
   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());
@@ -1807,6 +1807,7 @@
     return NULL;
   }
 
+  statuses = smartlist_create();
   SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
     if (ri->cache_info.published_on < cutoff)
       continue;

Modified: tor/trunk/src/or/onion.c
===================================================================
--- tor/trunk/src/or/onion.c	2008-01-16 04:15:41 UTC (rev 13146)
+++ tor/trunk/src/or/onion.c	2008-01-16 05:27:19 UTC (rev 13147)
@@ -336,14 +336,13 @@
   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 */
@@ -357,6 +356,9 @@
 
   tor_free(key_material);
   return 0;
+ err:
+  tor_free(key_material);
+  return -1;
 }
 
 /** Implement the server side of the CREATE_FAST abbreviated handshake.  The
@@ -429,6 +431,7 @@
     /* 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);

Modified: tor/trunk/src/or/rendservice.c
===================================================================
--- tor/trunk/src/or/rendservice.c	2008-01-16 04:15:41 UTC (rev 13146)
+++ tor/trunk/src/or/rendservice.c	2008-01-16 05:27:19 UTC (rev 13147)
@@ -284,6 +284,7 @@
         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);
@@ -292,6 +293,7 @@
         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);
@@ -308,6 +310,9 @@
         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);
@@ -317,6 +322,8 @@
        * 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) {
@@ -618,7 +625,7 @@
   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;

Modified: tor/trunk/src/or/router.c
===================================================================
--- tor/trunk/src/or/router.c	2008-01-16 04:15:41 UTC (rev 13146)
+++ tor/trunk/src/or/router.c	2008-01-16 05:27:19 UTC (rev 13147)
@@ -397,8 +397,10 @@
   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(),
@@ -1302,6 +1304,7 @@
   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 =

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2008-01-16 04:15:41 UTC (rev 13146)
+++ tor/trunk/src/or/routerlist.c	2008-01-16 05:27:19 UTC (rev 13147)
@@ -961,14 +961,14 @@
   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 =
@@ -2006,8 +2006,10 @@
   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));
   }

Modified: tor/trunk/src/or/routerparse.c
===================================================================
--- tor/trunk/src/or/routerparse.c	2008-01-16 04:15:41 UTC (rev 13146)
+++ tor/trunk/src/or/routerparse.c	2008-01-16 05:27:19 UTC (rev 13147)
@@ -789,7 +789,7 @@
   }
   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) {
@@ -797,10 +797,10 @@
     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;
 }
 
@@ -1090,7 +1090,7 @@
 
   if (router_get_router_hash(s, digest) < 0) {
     log_warn(LD_DIR, "Couldn't compute router hash.");
-    return NULL;
+    goto err;
   }
   {
     int flags = 0;

Modified: tor/trunk/src/tools/tor-gencert.c
===================================================================
--- tor/trunk/src/tools/tor-gencert.c	2008-01-16 04:15:41 UTC (rev 13146)
+++ tor/trunk/src/tools/tor-gencert.c	2008-01-16 05:27:19 UTC (rev 13147)
@@ -370,6 +370,8 @@
                "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);
 

Modified: tor/trunk/src/tools/tor-resolve.c
===================================================================
--- tor/trunk/src/tools/tor-resolve.c	2008-01-16 04:15:41 UTC (rev 13146)
+++ tor/trunk/src/tools/tor-resolve.c	2008-01-16 05:27:19 UTC (rev 13147)
@@ -195,6 +195,7 @@
   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) {