Browse Source

Merge remote-tracking branch 'public/bug10409_023' into maint-0.2.4

Nick Mathewson 10 years ago
parent
commit
3d5154550c
6 changed files with 62 additions and 7 deletions
  1. 3 0
      changes/bug10409
  2. 2 1
      src/or/dirvote.c
  3. 1 2
      src/or/microdesc.c
  4. 10 3
      src/or/routerparse.c
  5. 1 1
      src/or/routerparse.h
  6. 45 0
      src/test/test_microdesc.c

+ 3 - 0
changes/bug10409

@@ -0,0 +1,3 @@
+  o Minor bugfixes:
+    - Avoid a crash bug when starting with a corrupted microdescriptor
+      cache file. Fix for bug 10406; bugfix on 0.2.2.6-alpha.

+ 2 - 1
src/or/dirvote.c

@@ -3585,7 +3585,8 @@ dirvote_create_microdescriptor(const routerinfo_t *ri, int consensus_method)
 
   {
     smartlist_t *lst = microdescs_parse_from_string(output,
-                                                 output+strlen(output), 0, 1);
+                                                 output+strlen(output), 0,
+                                                    SAVED_NOWHERE);
     if (smartlist_len(lst) != 1) {
       log_warn(LD_DIR, "We generated a microdescriptor we couldn't parse.");
       SMARTLIST_FOREACH(lst, microdesc_t *, md, microdesc_free(md));

+ 1 - 2
src/or/microdesc.c

@@ -154,11 +154,10 @@ microdescs_add_to_cache(microdesc_cache_t *cache,
 {
   smartlist_t *descriptors, *added;
   const int allow_annotations = (where != SAVED_NOWHERE);
-  const int copy_body = (where != SAVED_IN_CACHE);
 
   descriptors = microdescs_parse_from_string(s, eos,
                                              allow_annotations,
-                                             copy_body);
+                                             where);
   if (listed_at > 0) {
     SMARTLIST_FOREACH(descriptors, microdesc_t *, md,
                       md->last_listed = listed_at);

+ 10 - 3
src/or/routerparse.c

@@ -4245,12 +4245,17 @@ find_start_of_next_microdesc(const char *s, const char *eos)
 
 /** Parse as many microdescriptors as are found from the string starting at
  * <b>s</b> and ending at <b>eos</b>.  If allow_annotations is set, read any
- * annotations we recognize and ignore ones we don't.  If <b>copy_body</b> is
- * true, then strdup the bodies of the microdescriptors.  Return all newly
+ * annotations we recognize and ignore ones we don't.
+ *
+ * If <b>saved_location</b> isn't SAVED_IN_CACHE, make a local copy of each
+ * descriptor in the body field of each microdesc_t.
+ *
+ * Return all newly
  * parsed microdescriptors in a newly allocated smartlist_t. */
 smartlist_t *
 microdescs_parse_from_string(const char *s, const char *eos,
-                             int allow_annotations, int copy_body)
+                             int allow_annotations,
+                             saved_location_t where)
 {
   smartlist_t *tokens;
   smartlist_t *result;
@@ -4259,6 +4264,7 @@ microdescs_parse_from_string(const char *s, const char *eos,
   const char *start = s;
   const char *start_of_next_microdesc;
   int flags = allow_annotations ? TS_ANNOTATIONS_OK : 0;
+  const int copy_body = (where != SAVED_IN_CACHE);
 
   directory_token_t *tok;
 
@@ -4288,6 +4294,7 @@ microdescs_parse_from_string(const char *s, const char *eos,
       tor_assert(cp);
 
       md->bodylen = start_of_next_microdesc - cp;
+      md->saved_location = where;
       if (copy_body)
         md->body = tor_memdup_nulterm(cp, md->bodylen);
       else

+ 1 - 1
src/or/routerparse.h

@@ -64,7 +64,7 @@ ns_detached_signatures_t *networkstatus_parse_detached_signatures(
 
 smartlist_t *microdescs_parse_from_string(const char *s, const char *eos,
                                           int allow_annotations,
-                                          int copy_body);
+                                          saved_location_t where);
 
 authority_cert_t *authority_cert_parse_from_string(const char *s,
                                                    const char **end_of_string);

+ 45 - 0
src/test/test_microdesc.c

@@ -240,8 +240,53 @@ test_md_cache(void *data)
   tor_free(fn);
 }
 
+static const char truncated_md[] =
+  "@last-listed 2013-08-08 19:02:59\n"
+  "onion-key\n"
+  "-----BEGIN RSA PUBLIC KEY-----\n"
+  "MIGJAoGBAM91vLFNaM+gGhnRIdz2Cm/Kl7Xz0cOobIdVzhS3cKUJfk867hCuTipS\n"
+  "NveLBzNopvgXKruAAzEj3cACxk6Q8lv5UWOGCD1UolkgsWSE62RBjap44g+oc9J1\n"
+  "RI9968xOTZw0VaBQg9giEILNXl0djoikQ+5tQRUvLDDa67gpa5Q1AgMBAAE=\n"
+  "-----END RSA PUBLIC KEY-----\n"
+  "family @\n";
+
+static void
+test_md_cache_broken(void *data)
+{
+  or_options_t *options;
+  char *fn=NULL;
+  microdesc_cache_t *mc = NULL;
+
+  (void)data;
+
+  options = get_options_mutable();
+  tt_assert(options);
+  options->DataDirectory = tor_strdup(get_fname("md_datadir_test2"));
+
+#ifdef _WIN32
+  tt_int_op(0, ==, mkdir(options->DataDirectory));
+#else
+  tt_int_op(0, ==, mkdir(options->DataDirectory, 0700));
+#endif
+
+  tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs",
+               options->DataDirectory);
+
+  write_str_to_file(fn, truncated_md, 1);
+
+  mc = get_microdesc_cache();
+  tt_assert(mc);
+
+ done:
+  if (options)
+    tor_free(options->DataDirectory);
+  tor_free(fn);
+  microdesc_free_all();
+}
+
 struct testcase_t microdesc_tests[] = {
   { "cache", test_md_cache, TT_FORK, NULL, NULL },
+  { "broken_cache", test_md_cache_broken, TT_FORK, NULL, NULL },
   END_OF_TESTCASES
 };