diff options
author | Mike Perry <mikeperry-git@fscked.org> | 2009-09-29 03:41:23 -0700 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2009-09-29 14:07:04 -0400 |
commit | f7e6e852e80c22b40a8f09bc1c85074726d7078e (patch) | |
tree | 8ba6086743027c5f7acb3ea645d8ccf6aedbfcbc /src/or/circuitbuild.c | |
parent | 2e70642c3a5dfbbb76cd9d04351e54530646b19a (diff) | |
download | tor-f7e6e852e80c22b40a8f09bc1c85074726d7078e.tar tor-f7e6e852e80c22b40a8f09bc1c85074726d7078e.tar.gz |
Fix 1108: Handle corrupt or large build times state.
1108 was actually just a fencepost error in an assert,
but making the state file handling code resilient is a
good idea.
Diffstat (limited to 'src/or/circuitbuild.c')
-rw-r--r-- | src/or/circuitbuild.c | 65 |
1 files changed, 45 insertions, 20 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 5c3a86c12..2e3465d6f 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -372,18 +372,29 @@ circuit_build_times_update_state(circuit_build_times_t *cbt, * Stolen from http://en.wikipedia.org/wiki/Fisher\u2013Yates_shuffle */ static void -circuit_build_times_shuffle_array(circuit_build_times_t *cbt) +circuit_build_times_shuffle_and_store_array(circuit_build_times_t *cbt, + build_time_t *raw_times, + int num_times) { - int n = cbt->total_build_times; - - /* This code can only be run on a compact array */ - tor_assert(cbt->total_build_times == cbt->build_times_idx); - while (n-- > 1) { - int k = crypto_rand_int(n + 1); /* 0 <= k <= n. */ - build_time_t tmp = cbt->circuit_build_times[k]; - cbt->circuit_build_times[k] = cbt->circuit_build_times[n]; - cbt->circuit_build_times[n] = tmp; - } + int n = num_times; + if (num_times > NCIRCUITS_TO_OBSERVE) { + log_notice(LD_CIRC, "Decreasing circuit_build_times size from %d to %d", + num_times, NCIRCUITS_TO_OBSERVE); + } + + /* This code can only be run on a compact array */ + while (n-- > 1) { + int k = crypto_rand_int(n + 1); /* 0 <= k <= n. */ + build_time_t tmp = raw_times[k]; + raw_times[k] = raw_times[n]; + raw_times[n] = tmp; + } + + /* Since the times are now shuffled, take a random NCIRCUITS_TO_OBSERVE + * subset (ie the first NCIRCUITS_TO_OBSERVE values) */ + for (n = 0; n < MIN(num_times, NCIRCUITS_TO_OBSERVE); n++) { + circuit_build_times_add_time(cbt, raw_times[n]); + } } /** @@ -397,14 +408,14 @@ int circuit_build_times_parse_state(circuit_build_times_t *cbt, or_state_t *state, char **msg) { - int tot_values = 0, N = 0; + int tot_values = 0; + uint32_t loaded_cnt = 0, N = 0; config_line_t *line; int i; - *msg = NULL; + build_time_t *loaded_times = tor_malloc(sizeof(build_time_t) + * state->TotalBuildTimes); circuit_build_times_init(cbt); - - /* We don't support decreasing the table size yet */ - tor_assert(state->TotalBuildTimes <= NCIRCUITS_TO_OBSERVE); + *msg = NULL; for (line = state->BuildtimeHistogram; line; line = line->next) { smartlist_t *args = smartlist_create(); @@ -441,17 +452,30 @@ circuit_build_times_parse_state(circuit_build_times_t *cbt, break; } + if (loaded_cnt+count > state->TotalBuildTimes) { + log_warn(LD_CIRC, + "Too many build times in state file. " + "Stopping short before %d", + loaded_cnt+count); + break; + } + for (k = 0; k < count; k++) { - circuit_build_times_add_time(cbt, ms); + loaded_times[loaded_cnt++] = ms; } N++; SMARTLIST_FOREACH(args, char*, cp, tor_free(cp)); smartlist_free(args); } + } + if (loaded_cnt != state->TotalBuildTimes) { + log_warn(LD_CIRC, + "Corrupt state file? Build times count mismatch. " + "Read %d, file says %d", loaded_cnt, state->TotalBuildTimes); } - circuit_build_times_shuffle_array(cbt); + circuit_build_times_shuffle_and_store_array(cbt, loaded_times, loaded_cnt); /* Verify that we didn't overwrite any indexes */ for (i=0; i < NCIRCUITS_TO_OBSERVE; i++) { @@ -462,9 +486,10 @@ circuit_build_times_parse_state(circuit_build_times_t *cbt, log_info(LD_CIRC, "Loaded %d/%d values from %d lines in circuit time histogram", tot_values, cbt->total_build_times, N); - tor_assert(cbt->total_build_times == state->TotalBuildTimes); - tor_assert(tot_values == cbt->total_build_times); + tor_assert(cbt->total_build_times == tot_values); + tor_assert(cbt->total_build_times <= NCIRCUITS_TO_OBSERVE); circuit_build_times_set_timeout(cbt); + tor_free(loaded_times); return *msg ? -1 : 0; } |