]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Set 'routerlist' global to NULL before freeing it.
authorNick Mathewson <nickm@torproject.org>
Fri, 19 Jul 2019 13:49:52 +0000 (09:49 -0400)
committerNick Mathewson <nickm@torproject.org>
Fri, 19 Jul 2019 13:49:52 +0000 (09:49 -0400)
There is other code that uses this value, and some of it is
apparently reachable from inside router_dir_info_changed(), which
routerlist_free() apparently calls.  (ouch!)  This is a minimal fix
to try to resolve the issue without causing other problems.

Fixes bug 31003. I'm calling this a bugfix on 0.1.2.2-alpha, where
the call to router_dir_info_changed() was added to routerlist_free().

changes/bug31003 [new file with mode: 0644]
src/feature/nodelist/routerlist.c

diff --git a/changes/bug31003 b/changes/bug31003
new file mode 100644 (file)
index 0000000..6c75163
--- /dev/null
@@ -0,0 +1,4 @@
+  o Minor bugfixes (crash on exit):
+    - Avoid a set of possible code paths that could use try to use freed memory
+      in routerlist_free() while Tor was exiting.  Fixes bug 31003; bugfix on
+      0.1.2.2-alpha.
index 4a99427cd62960b972e436c75d02f9589ef7d00d..61af09742d522e09ab804c2b0a474fac13f96859 100644 (file)
@@ -954,20 +954,18 @@ routerlist_free_(routerlist_t *rl)
   smartlist_free(rl->routers);
   smartlist_free(rl->old_routers);
   if (rl->desc_store.mmap) {
-    int res = tor_munmap_file(routerlist->desc_store.mmap);
+    int res = tor_munmap_file(rl->desc_store.mmap);
     if (res != 0) {
       log_warn(LD_FS, "Failed to munmap routerlist->desc_store.mmap");
     }
   }
   if (rl->extrainfo_store.mmap) {
-    int res = tor_munmap_file(routerlist->extrainfo_store.mmap);
+    int res = tor_munmap_file(rl->extrainfo_store.mmap);
     if (res != 0) {
       log_warn(LD_FS, "Failed to munmap routerlist->extrainfo_store.mmap");
     }
   }
   tor_free(rl);
-
-  router_dir_info_changed();
 }
 
 /** Log information about how much memory is being used for routerlist,
@@ -1426,8 +1424,10 @@ routerlist_reparse_old(routerlist_t *rl, signed_descriptor_t *sd)
 void
 routerlist_free_all(void)
 {
-  routerlist_free(routerlist);
-  routerlist = NULL;
+  routerlist_t *rl = routerlist;
+  routerlist = NULL; // Prevent internals of routerlist_free() from using
+                     // routerlist.
+  routerlist_free(rl);
   dirlist_free_all();
   if (warned_nicknames) {
     SMARTLIST_FOREACH(warned_nicknames, char *, cp, tor_free(cp));