[or-cvs] r10786: Possible partial fix for bug 455: use eos logic everywhere. (in tor/trunk: . src/common src/or)

nickm at seul.org nickm at seul.org
Tue Jul 10 20:08:18 UTC 2007


Author: nickm
Date: 2007-07-10 16:08:18 -0400 (Tue, 10 Jul 2007)
New Revision: 10786

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/src/common/util.c
   tor/trunk/src/common/util.h
   tor/trunk/src/or/routerparse.c
Log:
 r13687 at catbus:  nickm | 2007-07-10 16:08:14 -0400
 Possible partial fix for bug 455: use eos logic everywhere.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r13687] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2007-07-10 17:41:26 UTC (rev 10785)
+++ tor/trunk/ChangeLog	2007-07-10 20:08:18 UTC (rev 10786)
@@ -38,6 +38,8 @@
   o Major bugfixes (directory):
     - Fix a crash bug in directory authorities when we re-number the
       routerlist while inserting a new router. [Bugfix on 0.1.2.x]
+    - Fix a crash bug when router descriptors end at a 4096-byte boundary
+      on disk. [Bugfix on 0.1.2.x]
 
   o Minor bugfixes (directory):
     - Fix another crash bug related to extra-info caching.  (Bug found by

Modified: tor/trunk/src/common/util.c
===================================================================
--- tor/trunk/src/common/util.c	2007-07-10 17:41:26 UTC (rev 10785)
+++ tor/trunk/src/common/util.c	2007-07-10 20:08:18 UTC (rev 10786)
@@ -505,6 +505,15 @@
   return s;
 }
 
+/** DOCDOC */
+const char *
+eat_whitespace_eos_no_nl(const char *s, const char *eos)
+{
+  while (s < eos && (*s == ' ' || *s == '\t'))
+    ++s;
+  return s;
+}
+
 /** Return a pointer to the first char of s that is whitespace or <b>#</b>,
  * or to the terminating NUL if no such character exists.
  */
@@ -528,6 +537,29 @@
   }
 }
 
+/** DOCDOC */
+const char *
+find_whitespace_eos(const char *s, const char *eos)
+{
+  /* tor_assert(s); */
+  while (s < eos) {
+    switch (*s)
+    {
+    case '\0':
+    case '#':
+    case ' ':
+    case '\r':
+    case '\n':
+    case '\t':
+      return s;
+    default:
+      ++s;
+    }
+  }
+  return NULL;
+}
+
+
 /** Return true iff the 'len' bytes at 'mem' are all zero. */
 int
 tor_mem_is_zero(const char *mem, size_t len)

Modified: tor/trunk/src/common/util.h
===================================================================
--- tor/trunk/src/common/util.h	2007-07-10 17:41:26 UTC (rev 10785)
+++ tor/trunk/src/common/util.h	2007-07-10 20:08:18 UTC (rev 10786)
@@ -173,7 +173,9 @@
 const char *eat_whitespace(const char *s) ATTR_PURE;
 const char *eat_whitespace_eos(const char *s, const char *eos) ATTR_PURE;
 const char *eat_whitespace_no_nl(const char *s) ATTR_PURE;
+const char *eat_whitespace_eos_no_nl(const char *s, const char *eos) ATTR_PURE;
 const char *find_whitespace(const char *s) ATTR_PURE;
+const char *find_whitespace_eos(const char *s, const char *eos) ATTR_PURE;
 int tor_mem_is_zero(const char *mem, size_t len) ATTR_PURE;
 int tor_digest_is_zero(const char *digest) ATTR_PURE;
 char *esc_for_log(const char *string) ATTR_MALLOC;

Modified: tor/trunk/src/or/routerparse.c
===================================================================
--- tor/trunk/src/or/routerparse.c	2007-07-10 17:41:26 UTC (rev 10785)
+++ tor/trunk/src/or/routerparse.c	2007-07-10 20:08:18 UTC (rev 10786)
@@ -356,13 +356,14 @@
                            smartlist_t *out,
                            token_rule_t *table);
 static directory_token_t *get_next_token(const char **s,
+                                         const char *eos,
                                          token_rule_t *table);
 static int check_signature_token(const char *digest,
                                  directory_token_t *tok,
                                  crypto_pk_env_t *pkey,
                                  int check_authority,
                                  const char *doctype);
-static crypto_pk_env_t *find_dir_signing_key(const char *str);
+static crypto_pk_env_t *find_dir_signing_key(const char *str, const char *eos);
 static int tor_version_same_series(tor_version_t *a, tor_version_t *b);
 
 /** Set <b>digest</b> to the SHA-1 digest of the hash of the directory in
@@ -612,7 +613,7 @@
   if (tok->tp != K_DIRECTORY_SIGNATURE) {
     log_warn(LD_DIR,"Expected a single directory signature"); goto err;
   }
-  declared_key = find_dir_signing_key(str);
+  declared_key = find_dir_signing_key(str, str+strlen(str));
   note_crypto_pk_op(VERIFY_DIR);
   if (check_signature_token(digest, tok, declared_key, 1, "directory")<0)
     goto err;
@@ -673,13 +674,14 @@
   int r = -1;
   crypto_pk_env_t *declared_key = NULL;
   smartlist_t *tokens = NULL;
+  const char *eos = str + strlen(str);
 
   if (router_get_runningrouters_hash(str, digest)) {
     log_warn(LD_DIR, "Unable to compute digest of running-routers");
     goto err;
   }
   tokens = smartlist_create();
-  if (tokenize_string(str,str+strlen(str),tokens,dir_token_table)) {
+  if (tokenize_string(str,eos,tokens,dir_token_table)) {
     log_warn(LD_DIR, "Error tokenizing running-routers"); goto err;
   }
   tok = smartlist_get(tokens,0);
@@ -698,7 +700,7 @@
     log_warn(LD_DIR, "Missing signature on running-routers");
     goto err;
   }
-  declared_key = find_dir_signing_key(str);
+  declared_key = find_dir_signing_key(str, eos);
   note_crypto_pk_op(VERIFY_DIR);
   if (check_signature_token(digest, tok, declared_key, 1, "running-routers")
       < 0)
@@ -723,21 +725,23 @@
  * find the its dir-signing-key token (if any).  If this token is
  * present, extract and return the key.  Return NULL on failure. */
 static crypto_pk_env_t *
-find_dir_signing_key(const char *str)
+find_dir_signing_key(const char *str, const char *eos)
 {
   const char *cp;
   directory_token_t *tok;
   crypto_pk_env_t *key = NULL;
+  tor_assert(str);
+  tor_assert(eos);
 
   /* Is there a dir-signing-key in the directory? */
-  cp = strstr(str, "\nopt dir-signing-key");
+  cp = tor_memstr(str, eos-str, "\nopt dir-signing-key");
   if (!cp)
-    cp = strstr(str, "\ndir-signing-key");
+    cp = tor_memstr(str, eos-str, "\ndir-signing-key");
   if (!cp)
     return NULL;
   ++cp; /* Now cp points to the start of the token. */
 
-  tok = get_next_token(&cp, dir_token_table);
+  tok = get_next_token(&cp, eos, dir_token_table);
   if (!tok) {
     log_warn(LD_DIR, "Unparseable dir-signing-key token");
     return NULL;
@@ -2089,9 +2093,11 @@
   char *tmp;
   addr_policy_t *r;
   size_t len, idx;
+  const char *eos;
 
   /* *s might not end with \n, so we need to extend it with one. */
   len = strlen(s);
+  eos = s + len;
   cp = tmp = tor_malloc(len+2);
   for (idx = 0; idx < len; ++idx) {
     tmp[idx] = TOR_TOLOWER(s[idx]);
@@ -2107,7 +2113,7 @@
     tor_free(tmp);
     cp = tmp = new_str;
   }
-  tok = get_next_token(&cp, routerdesc_token_table);
+  tok = get_next_token(&cp, eos, routerdesc_token_table);
   if (tok->tp == _ERR) {
     log_warn(LD_DIR, "Error reading address policy: %s", tok->error);
     goto err;
@@ -2337,7 +2343,7 @@
  * of tokens in <b>table</b>.
  */
 static directory_token_t *
-get_next_token(const char **s, token_rule_t *table)
+get_next_token(const char **s, const char *eos, token_rule_t *table)
 {
   const char *next, *obstart;
   int i, j, done, allocated;
@@ -2358,22 +2364,22 @@
   tok = tor_malloc_zero(sizeof(directory_token_t));
   tok->tp = _ERR;
 
-  *s = eat_whitespace(*s);
+  *s = eat_whitespace_eos(*s, eos);
   if (!**s) {
     tok->tp = _EOF;
     return tok;
   }
-  next = find_whitespace(*s);
+  next = find_whitespace_eos(*s, eos);
   if (!next) {
     tok->error = tor_strdup("Unexpected EOF"); return tok;
   }
   /* It's a keyword... but which one? */
   if (!strncmp("opt", *s, next-*s)) {
     /* Skip past an "opt" at the start of the line. */
-    *s = eat_whitespace(next);
+    *s = eat_whitespace_eos(next, eos);
     next = NULL;
     if (**s)
-      next = find_whitespace(*s);
+      next = find_whitespace_eos(*s, eos);
     if (!**s || !next) {
       RET_ERR("opt without keyword");
     }
@@ -2395,14 +2401,14 @@
         tok->args = tor_malloc(sizeof(char*));
         tok->args[0] = tor_strndup(*s,next-*s);
         tok->n_args = 1;
-        *s = eat_whitespace_no_nl(next+1);
+        *s = eat_whitespace_eos_no_nl(next+1, eos);
       } else {
         /* This keyword takes multiple arguments. */
         j = 0;
         done = (*next == '\n');
         allocated = 32;
         tok->args = tor_malloc(sizeof(char*)*32);
-        *s = eat_whitespace_no_nl(next);
+        *s = eat_whitespace_eos_no_nl(next, eos);
         while (**s != '\n' && !done) {
           next = find_whitespace(*s);
           if (*next == '\n')
@@ -2412,7 +2418,7 @@
             tok->args = tor_realloc(tok->args,sizeof(char*)*allocated);
           }
           tok->args[j++] = tor_strndup(*s,next-*s);
-          *s = eat_whitespace_no_nl(next+1);
+          *s = eat_whitespace_eos_no_nl(next+1, eos);
         }
         tok->n_args = j;
       }
@@ -2429,17 +2435,17 @@
   }
   if (tok->tp == _ERR) {
     tok->tp = K_OPT;
-    *s = eat_whitespace_no_nl(next);
+    *s = eat_whitespace_eos_no_nl(next, eos);
     next = strchr(*s,'\n');
     if (!next)
       RET_ERR("Unexpected EOF");
     tok->args = tor_malloc(sizeof(char*));
     tok->args[0] = tor_strndup(*s,next-*s);
     tok->n_args = 1;
-    *s = eat_whitespace_no_nl(next+1);
+    *s = eat_whitespace_eos_no_nl(next+1, eos);
     o_syn = OBJ_OK;
   }
-  *s = eat_whitespace(*s);
+  *s = eat_whitespace_eos(*s, eos);
   if (strcmpstart(*s, "-----BEGIN ")) {
     goto check_object;
   }
@@ -2451,14 +2457,17 @@
   }
   tok->object_type = tor_strndup(*s, next-*s-5);
   *s = next+1;
-  next = strstr(*s, "-----END ");
+  next = tor_memstr(*s, eos-*s, "-----END ");
   if (!next) {
     RET_ERR("Malformed object: missing end line");
   }
   if (!strcmp(tok->object_type, "RSA PUBLIC KEY")) {
     if (strcmpstart(next, "-----END RSA PUBLIC KEY-----\n"))
       RET_ERR("Malformed object: mismatched end line");
-    next = strchr(next,'\n')+1;
+    next = memchr(next, '\n', eos-next);
+    if (!next)
+      RET_ERR("Couldn't parse public key.");
+    ++next;
     tok->key = crypto_new_pk_env();
     if (crypto_pk_read_public_key_from_string(tok->key, obstart, next-obstart))
       RET_ERR("Couldn't parse public key.");
@@ -2505,14 +2514,14 @@
   for (i = 0; i < _NIL; ++i)
     counts[i] = 0;
   while (*s < end && (!tok || tok->tp != _EOF)) {
-    tok = get_next_token(s, table);
+    tok = get_next_token(s, end, table);
     if (tok->tp == _ERR) {
       log_warn(LD_DIR, "parse error: %s", tok->error);
       return -1;
     }
     ++counts[tok->tp];
     smartlist_add(out, tok);
-    *s = eat_whitespace(*s);
+    *s = eat_whitespace_eos(*s, end);
   }
 
   for (i = 0; table[i].t; ++i) {



More information about the tor-commits mailing list