aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2012-08-03 12:04:11 -0400
committerNick Mathewson <nickm@torproject.org>2012-08-03 12:04:11 -0400
commit93be3a8822ae791cc8adb78ea7d7e76e4c10db41 (patch)
tree15a55487602f16aa8d6d757ff82958aa4e8357b4
parent82c5e385cbddec4fd80618d6e96111ad73d5a22e (diff)
parentd48cebc5e498b0ae673635f40fc57cdddab45d5b (diff)
downloadtor-93be3a8822ae791cc8adb78ea7d7e76e4c10db41.tar.gz
tor-93be3a8822ae791cc8adb78ea7d7e76e4c10db41.zip
Merge remote-tracking branch 'origin/maint-0.2.2' into maint-0.2.3
Conflicts: src/or/routerlist.c
-rw-r--r--changes/pathsel-BUGGY-a14
-rw-r--r--src/or/routerlist.c24
2 files changed, 33 insertions, 5 deletions
diff --git a/changes/pathsel-BUGGY-a b/changes/pathsel-BUGGY-a
new file mode 100644
index 0000000000..2e642c7953
--- /dev/null
+++ b/changes/pathsel-BUGGY-a
@@ -0,0 +1,14 @@
+ o Security fixes:
+
+ - Try to leak less information about what relays a client is
+ choosing to a side-channel attacker. Previously, a Tor client
+ would stop iterating through the list of available relays as
+ soon as it had chosen one, thus finishing a little earlier
+ when it picked a router earlier in the list. If an attacker
+ can recover this timing information (nontrivial but not
+ proven to be impossible), they could learn some coarse-
+ grained information about which relays a client was picking
+ (middle nodes in particular are likelier to be affected than
+ exits). The timing attack might be mitigated by other factors
+ (see bug #6537 for some discussion), but it's best not to
+ take chances. Fixes bug 6537; bugfix on 0.0.8rc1.
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 37de70f0b5..4979b933ad 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -1709,6 +1709,8 @@ smartlist_choose_node_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 */
@@ -1871,12 +1873,17 @@ smartlist_choose_node_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
@@ -1909,7 +1916,9 @@ static const node_t *
smartlist_choose_node_by_bandwidth(smartlist_t *sl,
bandwidth_weight_rule_t rule)
{
- unsigned i;
+ unsigned int i;
+ unsigned int i_chosen;
+ unsigned int i_has_been_chosen;
int32_t *bandwidths;
int is_exit;
int is_guard;
@@ -2109,6 +2118,8 @@ smartlist_choose_node_by_bandwidth(smartlist_t *sl,
/* 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);
@@ -2123,9 +2134,12 @@ smartlist_choose_node_by_bandwidth(smartlist_t *sl,
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. */