diff options
author | John Brooks <special@torproject.org> | 2016-05-11 12:13:22 -0400 |
---|---|---|
committer | John Brooks <special@torproject.org> | 2016-05-11 13:11:03 -0400 |
commit | bf3e32a45288b64e5535e02f40bd2bcb93c8a520 (patch) | |
tree | d3ae8afc737e828e69cbf6a583cadb0908a849f0 /src/or/dirserv.c | |
parent | 61c0bae4f20556cf155562582ea00a6a147252d6 (diff) | |
download | tor-bf3e32a45288b64e5535e02f40bd2bcb93c8a520.tar.gz tor-bf3e32a45288b64e5535e02f40bd2bcb93c8a520.zip |
Fix out-of-bounds write during voting with duplicate ed25519 keys
In dirserv_compute_performance_thresholds, we allocate arrays based
on the length of 'routers', a list of routerinfo_t, but loop over
the nodelist. The 'routers' list may be shorter when relays were
filtered by routers_make_ed_keys_unique, leading to an out-of-bounds
write on directory authorities.
This bug was originally introduced in 26e89742, but it doesn't look
possible to trigger until routers_make_ed_keys_unique was introduced
in 13a31e72.
Fixes bug 19032; bugfix on tor 0.2.8.2-alpha.
Diffstat (limited to 'src/or/dirserv.c')
-rw-r--r-- | src/or/dirserv.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c index ae67e8edb7..a367669db0 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1422,13 +1422,13 @@ router_counts_toward_thresholds(const node_t *node, time_t now, * * Also, set the is_exit flag of each router appropriately. */ static void -dirserv_compute_performance_thresholds(const smartlist_t *routers, - digestmap_t *omit_as_sybil) +dirserv_compute_performance_thresholds(digestmap_t *omit_as_sybil) { int n_active, n_active_nonexit, n_familiar; uint32_t *uptimes, *bandwidths_kb, *bandwidths_excluding_exits_kb; long *tks; double *mtbfs, *wfus; + smartlist_t *nodelist; time_t now = time(NULL); const or_options_t *options = get_options(); @@ -1446,27 +1446,28 @@ dirserv_compute_performance_thresholds(const smartlist_t *routers, guard_tk = 0; guard_wfu = 0; + nodelist_assert_ok(); + nodelist = nodelist_get_list(); + /* Initialize arrays that will hold values for each router. We'll * sort them and use that to compute thresholds. */ n_active = n_active_nonexit = 0; /* Uptime for every active router. */ - uptimes = tor_calloc(smartlist_len(routers), sizeof(uint32_t)); + uptimes = tor_calloc(smartlist_len(nodelist), sizeof(uint32_t)); /* Bandwidth for every active router. */ - bandwidths_kb = tor_calloc(smartlist_len(routers), sizeof(uint32_t)); + bandwidths_kb = tor_calloc(smartlist_len(nodelist), sizeof(uint32_t)); /* Bandwidth for every active non-exit router. */ bandwidths_excluding_exits_kb = - tor_calloc(smartlist_len(routers), sizeof(uint32_t)); + tor_calloc(smartlist_len(nodelist), sizeof(uint32_t)); /* Weighted mean time between failure for each active router. */ - mtbfs = tor_calloc(smartlist_len(routers), sizeof(double)); + mtbfs = tor_calloc(smartlist_len(nodelist), sizeof(double)); /* Time-known for each active router. */ - tks = tor_calloc(smartlist_len(routers), sizeof(long)); + tks = tor_calloc(smartlist_len(nodelist), sizeof(long)); /* Weighted fractional uptime for each active router. */ - wfus = tor_calloc(smartlist_len(routers), sizeof(double)); - - nodelist_assert_ok(); + wfus = tor_calloc(smartlist_len(nodelist), sizeof(double)); /* Now, fill in the arrays. */ - SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), node_t *, node) { + SMARTLIST_FOREACH_BEGIN(nodelist, node_t *, node) { if (options->BridgeAuthoritativeDir && node->ri && node->ri->purpose != ROUTER_PURPOSE_BRIDGE) @@ -1542,7 +1543,7 @@ dirserv_compute_performance_thresholds(const smartlist_t *routers, * fill wfus with the wfu of every such "familiar" router. */ n_familiar = 0; - SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), node_t *, node) { + SMARTLIST_FOREACH_BEGIN(nodelist, node_t *, node) { if (router_counts_toward_thresholds(node, now, omit_as_sybil, require_mbw)) { routerinfo_t *ri = node->ri; @@ -1596,11 +1597,11 @@ dirserv_compute_performance_thresholds(const smartlist_t *routers, * networkstatus_getinfo_by_purpose(). */ void -dirserv_compute_bridge_flag_thresholds(const smartlist_t *routers) +dirserv_compute_bridge_flag_thresholds() { digestmap_t *omit_as_sybil = digestmap_new(); - dirserv_compute_performance_thresholds(routers, omit_as_sybil); + dirserv_compute_performance_thresholds(omit_as_sybil); digestmap_free(omit_as_sybil, NULL); } @@ -2870,7 +2871,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, * this must come before dirserv_compute_performance_thresholds() */ dirserv_count_measured_bws(routers); - dirserv_compute_performance_thresholds(routers, omit_as_sybil); + dirserv_compute_performance_thresholds(omit_as_sybil); routerstatuses = smartlist_new(); microdescriptors = smartlist_new(); |