summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Ransom <rransom.8774@gmail.com>2012-06-14 17:15:54 +0000
committerNick Mathewson <nickm@torproject.org>2012-08-03 11:49:51 -0400
commit308f6dad20675c42b29862f4269ad1fbfb00dc9a (patch)
tree4c1e39fdfdafc9b705cef91549f08f7e3ca008db /src
parent55f635745afacefffdaafc72cc176ca7ab817546 (diff)
downloadtor-308f6dad20675c42b29862f4269ad1fbfb00dc9a.tar.gz
tor-308f6dad20675c42b29862f4269ad1fbfb00dc9a.zip
Mitigate a side-channel leak of which relays Tor chooses for a circuit
Tor's and OpenSSL's current design guarantee that there are other leaks, but this one is likely to be more easily exploitable, and is easy to fix.
Diffstat (limited to 'src')
-rw-r--r--src/or/routerlist.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index d21b40c57d..30c20bf6e6 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -1674,6 +1674,8 @@ smartlist_choose_by_bandwidth_weights(smartlist_t *sl,
double *bandwidths;
double tmp = 0;
unsigned int i;
+ unsigned int i_chosen;
+ unsigned int i_has_been_chosen;
int have_unknown = 0; /* true iff sl contains element not in consensus. */
/* Can't choose exit and guard at same time */
@@ -1835,12 +1837,17 @@ smartlist_choose_by_bandwidth_weights(smartlist_t *sl,
* from 1 below. See bug 1203 for details. */
/* Last, count through sl until we get to the element we picked */
+ i_chosen = (unsigned)smartlist_len(sl);
+ i_has_been_chosen = 0;
tmp = 0.0;
for (i=0; i < (unsigned)smartlist_len(sl); i++) {
tmp += bandwidths[i];
- if (tmp >= rand_bw)
- break;
+ if (tmp >= rand_bw && !i_has_been_chosen) {
+ i_chosen = i;
+ i_has_been_chosen = 1;
+ }
}
+ i = i_chosen;
if (i == (unsigned)smartlist_len(sl)) {
/* This was once possible due to round-off error, but shouldn't be able
@@ -1877,6 +1884,8 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, bandwidth_weight_rule_t rule,
int statuses)
{
unsigned int i;
+ unsigned int i_chosen;
+ unsigned int i_has_been_chosen;
routerinfo_t *router;
routerstatus_t *status=NULL;
int32_t *bandwidths;
@@ -2092,6 +2101,8 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, bandwidth_weight_rule_t rule,
/* Last, count through sl until we get to the element we picked */
tmp = 0;
+ i_chosen = (unsigned)smartlist_len(sl);
+ i_has_been_chosen = 0;
for (i=0; i < (unsigned)smartlist_len(sl); i++) {
is_exit = bitarray_is_set(exit_bits, i);
is_guard = bitarray_is_set(guard_bits, i);
@@ -2106,9 +2117,12 @@ smartlist_choose_by_bandwidth(smartlist_t *sl, bandwidth_weight_rule_t rule,
else
tmp += bandwidths[i];
- if (tmp >= rand_bw)
- break;
+ if (tmp >= rand_bw && !i_has_been_chosen) {
+ i_chosen = i;
+ i_has_been_chosen = 1;
+ }
}
+ i = i_chosen;
if (i == (unsigned)smartlist_len(sl)) {
/* This was once possible due to round-off error, but shouldn't be able
* to occur any longer. */