浏览代码

Fix an impossible-in-normal-operation leaks in dirvote

Spotted by coverity; partial fix for 7816; bugfix on 0.2.0.5-alpha.
Nick Mathewson 11 年之前
父节点
当前提交
f272ee6a20
共有 2 个文件被更改,包括 15 次插入9 次删除
  1. 4 0
      changes/bug7816.024
  2. 11 9
      src/or/dirvote.c

+ 4 - 0
changes/bug7816.024

@@ -2,3 +2,7 @@
     - Avoid leaking IPv6 policy content if we fail to format it into
       a router descriptor. Spotted by Coverity. Fixes part of 7816;
       bugfix on 0.2.4.7-alpha.
+
+    - Avoid leaking memory if we fail to compute a consensus signature
+      or we generated a consensus we couldn't parse. Spotted by Coverity.
+      Fixes part of 7816; bugfix on 0.2.0.5-alpha.

+ 11 - 9
src/or/dirvote.c

@@ -2139,7 +2139,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
                                          digest, digest_len,
                                          legacy_signing_key)) {
         log_warn(LD_BUG, "Couldn't sign consensus networkstatus.");
-        return NULL; /* This leaks, but it should never happen. */
+        goto done;
       }
       smartlist_add(chunks, tor_strdup(sigbuf));
     }
@@ -2147,13 +2147,6 @@ networkstatus_compute_consensus(smartlist_t *votes,
 
   result = smartlist_join_strings(chunks, "", 0, NULL);
 
-  tor_free(client_versions);
-  tor_free(server_versions);
-  SMARTLIST_FOREACH(flags, char *, cp, tor_free(cp));
-  smartlist_free(flags);
-  SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
-  smartlist_free(chunks);
-
   {
     networkstatus_t *c;
     if (!(c = networkstatus_parse_vote_from_string(result, NULL,
@@ -2161,7 +2154,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
       log_err(LD_BUG, "Generated a networkstatus consensus we couldn't "
               "parse.");
       tor_free(result);
-      return NULL;
+      goto done;
     }
     // Verify balancing parameters
     if (consensus_method >= MIN_METHOD_FOR_BW_WEIGHTS && added_weights) {
@@ -2170,6 +2163,15 @@ networkstatus_compute_consensus(smartlist_t *votes,
     networkstatus_vote_free(c);
   }
 
+ done:
+
+  tor_free(client_versions);
+  tor_free(server_versions);
+  SMARTLIST_FOREACH(flags, char *, cp, tor_free(cp));
+  smartlist_free(flags);
+  SMARTLIST_FOREACH(chunks, char *, cp, tor_free(cp));
+  smartlist_free(chunks);
+
   return result;
 }