Преглед изворни кода

Merge remote-tracking branch 'origin/maint-0.2.2'

Conflicts:
	src/or/connection.c
Nick Mathewson пре 13 година
родитељ
комит
acd6a4856b

+ 4 - 0
changes/dirvote_null_deref

@@ -0,0 +1,4 @@
+  o Minor bugfixes:
+    - Fix a potential null-pointer dereference while computing a consensus.
+      Bugfix on tor-0.2.0.3-alpha, found with the help of clang's analyzer.
+

+ 5 - 0
changes/mdesc_null_deref

@@ -0,0 +1,5 @@
+  o Minor bugfixes:
+    - Avoid a possible null-pointer dereference when rebuilding the mdesc
+      cache without actually having any descriptors to cache. Bugfix on
+      0.2.2.6-alpha. Issue discovered using clang's static analyzer.
+

+ 11 - 1
src/or/circuitbuild.c

@@ -560,7 +560,9 @@ circuit_build_times_create_histogram(circuit_build_times_t *cbt,
  * Return the Pareto start-of-curve parameter Xm.
  *
  * Because we are not a true Pareto curve, we compute this as the
- * weighted average of the N=3 most frequent build time bins.
+ * weighted average of the N most frequent build time bins. N is either
+ * 1 if we don't have enough circuit build time data collected, or
+ * determined by the consensus parameter cbtnummodes (default 3).
  */
 static build_time_t
 circuit_build_times_get_xm(circuit_build_times_t *cbt)
@@ -573,6 +575,9 @@ circuit_build_times_get_xm(circuit_build_times_t *cbt)
   int n=0;
   int num_modes = circuit_build_times_default_num_xm_modes();
 
+  tor_assert(nbins > 0);
+  tor_assert(num_modes > 0);
+
   // Only use one mode if < 1000 buildtimes. Not enough data
   // for multiple.
   if (cbt->total_build_times < CBT_NCIRCUITS_TO_OBSERVE)
@@ -580,6 +585,7 @@ circuit_build_times_get_xm(circuit_build_times_t *cbt)
 
   nth_max_bin = (build_time_t*)tor_malloc_zero(num_modes*sizeof(build_time_t));
 
+  /* Determine the N most common build times */
   for (i = 0; i < nbins; i++) {
     if (histogram[i] >= histogram[nth_max_bin[0]]) {
       nth_max_bin[0] = i;
@@ -601,6 +607,10 @@ circuit_build_times_get_xm(circuit_build_times_t *cbt)
              histogram[nth_max_bin[n]]);
   }
 
+  /* The following assert is safe, because we don't get called when we
+   * haven't observed at least CBT_MIN_MIN_CIRCUITS_TO_OBSERVE circuits. */
+  tor_assert(bin_counts > 0);
+
   ret /= bin_counts;
   tor_free(histogram);
   tor_free(nth_max_bin);

+ 1 - 1
src/or/connection.c

@@ -1283,7 +1283,7 @@ connection_connect(connection_t *conn, const char *address,
 {
   int s, inprogress = 0;
   char addrbuf[256];
-  struct sockaddr *dest_addr = (struct sockaddr*) addrbuf;
+  struct sockaddr *dest_addr;
   int dest_addr_len;
   or_options_t *options = get_options();
   int protocol_family;

+ 1 - 2
src/or/connection_or.c

@@ -1565,9 +1565,8 @@ connection_or_send_netinfo(or_connection_t *conn)
     len = append_address_to_payload(out, &my_addr);
     if (len < 0)
       return -1;
-    out += len;
   } else {
-    *out++ = 0;
+    *out = 0;
   }
 
   connection_or_write_cell_to_buf(&cell, conn);

+ 4 - 1
src/or/control.c

@@ -3997,7 +3997,7 @@ static int bootstrap_problems = 0;
  * information and initial circuits.
  *
  * <b>status</b> is the new status, that is, what task we will be doing
- * next. <b>percent</b> is zero if we just started this task, else it
+ * next. <b>progress</b> is zero if we just started this task, else it
  * represents progress on the task. */
 void
 control_event_bootstrap(bootstrap_status_t status, int progress)
@@ -4053,6 +4053,9 @@ control_event_bootstrap_problem(const char *warn, int reason)
   char buf[BOOTSTRAP_MSG_LEN];
   const char *recommendation = "ignore";
 
+  /* bootstrap_percent must not be in "undefined" state here. */
+  tor_assert(status >= 0);
+
   if (bootstrap_percent == 100)
     return; /* already bootstrapped; nothing to be done here. */
 

+ 3 - 3
src/or/dirvote.c

@@ -441,9 +441,9 @@ compute_routerstatus_consensus(smartlist_t *votes, int consensus_method,
     if (cur && !compare_vote_rs(cur, rs)) {
       ++cur_n;
     } else {
-      if (cur_n > most_n ||
-          (cur && cur_n == most_n &&
-           cur->status.published_on > most_published)) {
+      if (cur && (cur_n > most_n ||
+                  (cur_n == most_n &&
+                   cur->status.published_on > most_published))) {
         most = cur;
         most_n = cur_n;
         most_published = cur->status.published_on;

+ 1 - 1
src/or/microdesc.c

@@ -487,7 +487,7 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
   cache->journal_len = 0;
   cache->bytes_dropped = 0;
 
-  new_size = (int)cache->cache_content->size;
+  new_size = cache->cache_content ? (int)cache->cache_content->size : 0;
   log_info(LD_DIR, "Done rebuilding microdesc cache. "
            "Saved %d bytes; %d still used.",
            orig_size-new_size, new_size);

+ 3 - 1
src/or/or.h

@@ -3388,7 +3388,9 @@ typedef enum buildtimeout_set_event_t {
  */
 #define CONN_LOG_PROTECT(conn, stmt)                                    \
   STMT_BEGIN                                                            \
-    int _log_conn_is_control = (conn && conn->type == CONN_TYPE_CONTROL); \
+    int _log_conn_is_control;                                           \
+    tor_assert(conn);                                                   \
+    _log_conn_is_control = (conn->type == CONN_TYPE_CONTROL);           \
     if (_log_conn_is_control)                                           \
       disable_control_logging();                                        \
   STMT_BEGIN stmt; STMT_END;                                            \