From 98aee8472f8028260f85b69499fa892060c9534c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 20 Oct 2010 12:34:02 -0400 Subject: [PATCH 1/2] Fix a read of a freed pointer while in set_current_consensus Found by rransom while working on issue #988. Bugfix on 0.2.2.17-alpha. Fixes bug 2097. --- changes/set_ns_crash | 4 ++++ src/or/networkstatus.c | 18 +++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 changes/set_ns_crash diff --git a/changes/set_ns_crash b/changes/set_ns_crash new file mode 100644 index 0000000000..34466d7ad0 --- /dev/null +++ b/changes/set_ns_crash @@ -0,0 +1,4 @@ + o Major bugfixes: + - Avoid a crash bug triggered by looking at a dangling pointer while + setting the network status consensus. Found by Robert Ransom. + Bugfix on 0.2.2.17-alpha. Fixes bug 2097. diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c index 1d8a20be11..27049d9ef2 100644 --- a/src/or/networkstatus.c +++ b/src/or/networkstatus.c @@ -1706,6 +1706,10 @@ networkstatus_set_current_consensus(const char *consensus, if (current_consensus) { networkstatus_copy_old_consensus_info(c, current_consensus); networkstatus_vote_free(current_consensus); + /* Defensive programming : we should set current_consensus very soon, + * but we're about to call some stuff in the meantime, and leaving this + * dangling pointer around has proven to be trouble. */ + current_consensus = NULL; } } @@ -1731,13 +1735,6 @@ networkstatus_set_current_consensus(const char *consensus, download_status_failed(&consensus_dl_status[flav], 0); } - if (directory_caches_dir_info(options)) { - dirserv_set_cached_consensus_networkstatus(consensus, - flavor, - &c->digests, - c->valid_after); - } - if (flav == USABLE_CONSENSUS_FLAVOR) { current_consensus = c; c = NULL; /* Prevent free. */ @@ -1754,6 +1751,13 @@ networkstatus_set_current_consensus(const char *consensus, circuit_build_times_new_consensus_params(&circ_times, current_consensus); } + if (directory_caches_dir_info(options)) { + dirserv_set_cached_consensus_networkstatus(consensus, + flavor, + &c->digests, + c->valid_after); + } + if (!from_cache) { write_str_to_file(consensus_fname, consensus, 0); } From 2849a95691c002108666eb414ff497bf93349e7d Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 20 Oct 2010 13:49:38 -0400 Subject: [PATCH 2/2] Add a ! to directory_caches_dir_info() to fix a logic error We want to fetch directory info more aggressively if we need it to refuseunknownexits. Thus, we'll want it if our exit policy is _NOT_ reject *. --- changes/caches_if_exit | 5 +++++ src/or/dirserv.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changes/caches_if_exit diff --git a/changes/caches_if_exit b/changes/caches_if_exit new file mode 100644 index 0000000000..0e662270e2 --- /dev/null +++ b/changes/caches_if_exit @@ -0,0 +1,5 @@ + o Minor bugfixes: + - Fix a logic error where servers that _didn't_ act as exits would + try to keep their server lists more aggressively up to date than + exits, when it was supposed to be the other way around. Bugfix + on 0.2.2.17-alpha. diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 8ae03424a2..8d0ec981a7 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -1213,7 +1213,7 @@ directory_caches_dir_info(or_options_t *options) return 0; /* We need an up-to-date view of network info if we're going to try to * block exit attempts from unknown relays. */ - return router_my_exit_policy_is_reject_star() && + return ! router_my_exit_policy_is_reject_star() && should_refuse_unknown_exits(options); }