From f7acc3cfa01ca5cb728401956e0ea3fef1cfe6e0 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 30 Apr 2007 05:32:57 +0000 Subject: [PATCH] r12553@catbus: nickm | 2007-04-30 01:32:54 -0400 Backport candidate: Add asserts to dirserv_remove_invalid, and fix a bug in dirserv_remove_invalid that could mess with pointers in a freed routerinfo right after it was freed. svn:r10052 --- ChangeLog | 3 +++ src/or/dirserv.c | 5 +++++ src/or/routerlist.c | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 6ff3ca1bb1..80da7f5e73 100644 --- a/ChangeLog +++ b/ChangeLog @@ -86,6 +86,9 @@ Changes in version 0.2.0.1-alpha - 2007-??-?? we restart. - Correctly enforce that elements of directory objects do not appear more often than they are allowed to appear. + - Fix a bug in dirserv_remove_invalid() that would cause authorities to + corrupt memory under some really unlikely scenarios. + - Add even more asserts to hunt down bug 417. o Minor bugfixes (controller), reported by daejees: - Make 'getinfo fingerprint' return a 551 error if we're not a diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 415810ebfd..1effd10bff 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -621,6 +621,8 @@ directory_remove_invalid(void) int changed = 0; routerlist_t *rl = router_get_routerlist(); + routerlist_assert_ok(rl); + for (i = 0; i < smartlist_len(rl->routers); ++i) { const char *msg; routerinfo_t *ent = smartlist_get(rl->routers, i); @@ -630,6 +632,7 @@ directory_remove_invalid(void) ent->nickname, msg?msg:""); routerlist_remove(rl, ent, i--, 0); changed = 1; + continue; } if (bool_neq((r & FP_NAMED), ent->is_named)) { log_info(LD_DIRSERV, @@ -653,6 +656,8 @@ directory_remove_invalid(void) } if (changed) directory_set_dirty(); + + routerlist_assert_ok(rl); } /** Write a list of unregistered descriptors into a newly allocated diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 0dfa4dbcaf..c211d7c1c6 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -4674,7 +4674,7 @@ routerlist_assert_ok(routerlist_t *rl) digestmap_iter_t *iter; routerinfo_t *r2; signed_descriptor_t *sd2; - if (!routerlist) + if (!rl); return; SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r, {