]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Unmap the microdescriptor cache before replacing it.
authorNick Mathewson <nickm@torproject.org>
Wed, 12 Jun 2013 16:04:33 +0000 (12:04 -0400)
committerNick Mathewson <nickm@torproject.org>
Wed, 12 Jun 2013 16:04:33 +0000 (12:04 -0400)
This is a reprise of the fix in bdff7e3299d786905c1f6 reintroduced
that bug.  Briefly: windows doesn't seem to like deleting a mapped
file.  I tried adding the PROT_SHARED_DELETE flag to the createfile
all, but that didn't actually fix this issue.  Fortunately, the unit
test I added in 4f4fc63fea0589a4fa03f3859dc27860cdde75af should
prevent us from making this particular screw-up again.

This patch also tries to limit the crash potential of a failure to
write by a little bit, although it could do a better job of retaining
microdescriptor bodies.

Fix for bug 8822, bugfix on 0.2.4.12-alpha.

changes/bug8822 [new file with mode: 0644]
src/or/microdesc.c

diff --git a/changes/bug8822 b/changes/bug8822
new file mode 100644 (file)
index 0000000..c6787af
--- /dev/null
@@ -0,0 +1,5 @@
+  o Major bugfixes (windows):
+    - Prevent failures on Windows Vista and later when rebuilding the
+      microdescriptor cache. Diagnosed by Robert Ransom. Fixes bug 8822;
+      bugfix on 0.2.4.12-alpha.
+
index d9955c7b49bdad0b11074b14f5d3c7247d43cb97..f99e1c88adaf21d19d69da604c4ccbb317615df7 100644 (file)
@@ -474,15 +474,29 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
     smartlist_add(wrote, md);
   }
 
+  /* We must do this unmap _before_ we call finish_writing_to_file(), or
+   * windows will not actually replace the file. */
+  if (cache->cache_content)
+    tor_munmap_file(cache->cache_content);
+
   if (finish_writing_to_file(open_file) < 0) {
     log_warn(LD_DIR, "Error rebuilding microdescriptor cache: %s",
              strerror(errno));
+    /* Okay. Let's prevent from making things worse elsewhere. */
+    cache->cache_content = NULL;
+    HT_FOREACH(mdp, microdesc_map, &cache->map) {
+      microdesc_t *md = *mdp;
+      if (md->saved_location == SAVED_IN_CACHE) {
+        md->off = 0;
+        md->saved_location = SAVED_NOWHERE;
+        md->body = NULL;
+        md->bodylen = 0;
+        md->no_save = 1;
+      }
+    }
     return -1;
   }
 
-  if (cache->cache_content)
-    tor_munmap_file(cache->cache_content);
-
   cache->cache_content = tor_mmap_file(cache->cache_fname);
 
   if (!cache->cache_content && smartlist_len(wrote)) {