[or-cvs] [tor/master] Merge remote branch 'origin/maint-0.2.2'

nickm at torproject.org nickm at torproject.org
Sat Jan 15 19:19:47 UTC 2011


commit 1758ef51de8b44141184a36bcd36dea349d9e65d
Merge: 7ea674e 1393985
Author: Nick Mathewson <nickm at torproject.org>
Date:   Sat Jan 15 13:26:02 2011 -0500

    Merge remote branch 'origin/maint-0.2.2'

 changes/bug2352      |    6 ++++++
 src/common/crypto.c  |   14 ++++++++------
 src/common/crypto.h  |    2 +-
 src/or/routerparse.c |   16 ++++++++++++----
 src/test/test_dir.c  |    6 +++---
 5 files changed, 30 insertions(+), 14 deletions(-)

diff --combined src/common/crypto.c
index 127224d,1d12a9d..668851a
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@@ -518,21 -518,23 +518,23 @@@ crypto_pk_generate_key_with_bits(crypto
    return 0;
  }
  
- /** Read a PEM-encoded private key from the string <b>s</b> into <b>env</b>.
-  * Return 0 on success, -1 on failure.
+ /** Read a PEM-encoded private key from the <b>len</b>-byte string <b>s</b>
+  * into <b>env</b>.  Return 0 on success, -1 on failure.  If len is -1,
+  * the string is nul-terminated.
   */
  /* Used here, and used for testing. */
  int
  crypto_pk_read_private_key_from_string(crypto_pk_env_t *env,
-                                        const char *s)
+                                        const char *s, ssize_t len)
  {
    BIO *b;
  
    tor_assert(env);
    tor_assert(s);
+   tor_assert(len < INT_MAX && len < SIZE_T_CEILING);
  
-   /* Create a read-only memory BIO, backed by the NUL-terminated string 's' */
-   b = BIO_new_mem_buf((char*)s, -1);
+   /* Create a read-only memory BIO, backed by the string 's' */
+   b = BIO_new_mem_buf((char*)s, (int)len);
  
    if (env->key)
      RSA_free(env->key);
@@@ -566,7 -568,7 +568,7 @@@ crypto_pk_read_private_key_from_filenam
    }
  
    /* Try to parse it. */
-   r = crypto_pk_read_private_key_from_string(env, contents);
+   r = crypto_pk_read_private_key_from_string(env, contents, -1);
    tor_free(contents);
    if (r)
      return -1; /* read_private_key_from_string already warned, so we don't.*/
@@@ -923,7 -925,7 +925,7 @@@ crypto_pk_public_checksig_digest(crypto
      log_warn(LD_BUG, "couldn't compute digest");
      return -1;
    }
 -  buflen = crypto_pk_keysize(env)+1;
 +  buflen = crypto_pk_keysize(env);
    buf = tor_malloc(buflen);
    r = crypto_pk_public_checksig(env,buf,buflen,sig,siglen);
    if (r != DIGEST_LEN) {
@@@ -1108,8 -1110,8 +1110,8 @@@ crypto_pk_private_hybrid_decrypt(crypto
                                       warnOnFailure);
    }
  
 -  buf = tor_malloc(pkeylen+1);
 -  outlen = crypto_pk_private_decrypt(env,buf,pkeylen+1,from,pkeylen,padding,
 +  buf = tor_malloc(pkeylen);
 +  outlen = crypto_pk_private_decrypt(env,buf,pkeylen,from,pkeylen,padding,
                                       warnOnFailure);
    if (outlen<0) {
      log_fn(warnOnFailure?LOG_WARN:LOG_DEBUG, LD_CRYPTO,
@@@ -2659,3 -2661,4 +2661,3 @@@ setup_openssl_threading(void
    return 0;
  }
  #endif
 -
diff --combined src/common/crypto.h
index b44efcc,c306bec..ee27831
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@@ -112,7 -112,7 +112,7 @@@ int crypto_pk_write_private_key_to_stri
  int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env,
                                            const char *src, size_t len);
  int crypto_pk_read_private_key_from_string(crypto_pk_env_t *env,
-                                            const char *s);
+                                            const char *s, ssize_t len);
  int crypto_pk_write_private_key_to_filename(crypto_pk_env_t *env,
                                              const char *fname);
  
@@@ -240,8 -240,7 +240,8 @@@ void secret_to_key(char *key_out, size_
                     size_t secret_len, const char *s2k_specifier);
  
  #ifdef CRYPTO_PRIVATE
 -/* Prototypes for private functions only used by tortls.c and crypto.c */
 +/* Prototypes for private functions only used by tortls.c, crypto.c, and the
 + * unit tests. */
  struct rsa_st;
  struct evp_pkey_st;
  struct dh_st;
diff --combined src/or/routerparse.c
index 56d86bd,a6eef2d..fbceda1
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@@ -69,6 -69,7 +69,6 @@@ typedef enum 
    K_V,
    K_W,
    K_M,
 -  K_EVENTDNS,
    K_EXTRA_INFO,
    K_EXTRA_INFO_DIGEST,
    K_CACHES_EXTRA_INFO,
@@@ -285,6 -286,7 +285,6 @@@ static token_rule_t routerdesc_token_ta
  
    T01("family",              K_FAMILY,              ARGS,    NO_OBJ ),
    T01("caches-extra-info",   K_CACHES_EXTRA_INFO,   NO_ARGS, NO_OBJ ),
 -  T01("eventdns",            K_EVENTDNS,            ARGS,    NO_OBJ ),
  
    T0N("opt",                 K_OPT,             CONCAT_ARGS, OBJ_OK ),
    T1( "bandwidth",           K_BANDWIDTH,           GE(3),   NO_OBJ ),
@@@ -1354,6 -1356,7 +1354,6 @@@ router_parse_entry_from_string(const ch
    tor_assert(tok->n_args >= 5);
  
    router = tor_malloc_zero(sizeof(routerinfo_t));
 -  router->country = -1;
    router->cache_info.routerlist_index = -1;
    router->cache_info.annotations_len = s-start_of_annotations + prepend_len;
    router->cache_info.signed_descriptor_len = end-s;
@@@ -1494,6 -1497,13 +1494,6 @@@
      router->contact_info = tor_strdup(tok->args[0]);
    }
  
 -  if ((tok = find_opt_by_keyword(tokens, K_EVENTDNS))) {
 -    router->has_old_dnsworkers = tok->n_args && !strcmp(tok->args[0], "0");
 -  } else if (router->platform) {
 -    if (! tor_version_as_new_as(router->platform, "0.1.2.2-alpha"))
 -      router->has_old_dnsworkers = 1;
 -  }
 -
    exit_policy_tokens = find_all_exitpolicy(tokens);
    if (!smartlist_len(exit_policy_tokens)) {
      log_warn(LD_DIR, "No exit policy tokens in descriptor.");
@@@ -1552,6 -1562,8 +1552,6 @@@
                              "router descriptor") < 0)
      goto err;
  
 -  routerinfo_set_country(router);
 -
    if (!router->or_port) {
      log_warn(LD_DIR,"or_port unreadable or 0. Failing.");
      goto err;
@@@ -1941,7 -1953,6 +1941,7 @@@ routerstatus_parse_entry_from_string(me
  
    if (!consensus_method)
      flav = FLAV_NS;
 +  tor_assert(flav == FLAV_NS || flav == FLAV_MICRODESC);
  
    eos = find_start_of_next_routerstatus(*s);
  
@@@ -1954,16 -1965,15 +1954,16 @@@
      goto err;
    }
    tok = find_by_keyword(tokens, K_R);
 -  tor_assert(tok->n_args >= 7);
 +  tor_assert(tok->n_args >= 7); /* guaranteed by GE(7) in K_R setup */
    if (flav == FLAV_NS) {
      if (tok->n_args < 8) {
        log_warn(LD_DIR, "Too few arguments to r");
        goto err;
      }
 -  } else {
 -    offset = -1;
 +  } else if (flav == FLAV_MICRODESC) {
 +    offset = -1; /* There is no identity digest */
    }
 +
    if (vote_rs) {
      rs = &vote_rs->status;
    } else {
@@@ -2037,7 -2047,7 +2037,7 @@@
        else if (!strcmp(tok->args[i], "Fast"))
          rs->is_fast = 1;
        else if (!strcmp(tok->args[i], "Running"))
 -        rs->is_running = 1;
 +        rs->is_flagged_running = 1;
        else if (!strcmp(tok->args[i], "Named"))
          rs->is_named = 1;
        else if (!strcmp(tok->args[i], "Valid"))
@@@ -2139,16 -2149,6 +2139,16 @@@
          vote_rs->microdesc = line;
        }
      } SMARTLIST_FOREACH_END(t);
 +  } else if (flav == FLAV_MICRODESC) {
 +    tok = find_opt_by_keyword(tokens, K_M);
 +    if (tok) {
 +      tor_assert(tok->n_args);
 +      if (digest256_from_base64(rs->descriptor_digest, tok->args[0])) {
 +        log_warn(LD_DIR, "Error decoding microdescriptor digest %s",
 +                 escaped(tok->args[0]));
 +        goto err;
 +      }
 +    }
    }
  
    if (!strcasecmp(rs->nickname, UNNAMED_ROUTER_NICKNAME))
@@@ -3227,7 -3227,7 +3227,7 @@@ networkstatus_parse_vote_from_string(co
        }
        sig->good_signature = 1;
      } else {
-       if (tok->object_size >= INT_MAX) {
+       if (tok->object_size >= INT_MAX || tok->object_size >= SIZE_T_CEILING) {
          tor_free(sig);
          goto err;
        }
@@@ -3496,7 -3496,7 +3496,7 @@@ networkstatus_parse_detached_signatures
      sig->alg = alg;
      memcpy(sig->identity_digest, id_digest, DIGEST_LEN);
      memcpy(sig->signing_key_digest, sk_digest, DIGEST_LEN);
-     if (tok->object_size >= INT_MAX) {
+     if (tok->object_size >= INT_MAX || tok->object_size >= SIZE_T_CEILING) {
        tor_free(sig);
        goto err;
      }
@@@ -3814,6 -3814,10 +3814,10 @@@ static directory_token_t 
  get_next_token(memarea_t *area,
                 const char **s, const char *eos, token_rule_t *table)
  {
+   /** Reject any object at least this big; it is probably an overflow, an
+    * attack, a bug, or some other nonsense. */
+ #define MAX_UNPARSED_OBJECT_SIZE (128*1024)
+ 
    const char *next, *eol, *obstart;
    size_t obname_len;
    int i;
@@@ -3898,7 -3902,8 +3902,8 @@@
  
    obstart = *s; /* Set obstart to start of object spec */
    if (*s+16 >= eol || memchr(*s+11,'\0',eol-*s-16) || /* no short lines, */
-       strcmp_len(eol-5, "-----", 5)) {          /* nuls or invalid endings */
+       strcmp_len(eol-5, "-----", 5) ||           /* nuls or invalid endings */
+       (eol-*s) > MAX_UNPARSED_OBJECT_SIZE) {     /* name too long */
      RET_ERR("Malformed object: bad begin line");
    }
    tok->object_type = STRNDUP(*s+11, eol-*s-16);
@@@ -3923,13 -3928,16 +3928,16 @@@
      ebuf[sizeof(ebuf)-1] = '\0';
      RET_ERR(ebuf);
    }
+   if (next - *s > MAX_UNPARSED_OBJECT_SIZE)
+     RET_ERR("Couldn't parse object: missing footer or object much too big.");
+ 
    if (!strcmp(tok->object_type, "RSA PUBLIC KEY")) { /* If it's a public key */
      tok->key = crypto_new_pk_env();
      if (crypto_pk_read_public_key_from_string(tok->key, obstart, eol-obstart))
        RET_ERR("Couldn't parse public key.");
    } else if (!strcmp(tok->object_type, "RSA PRIVATE KEY")) { /* private key */
      tok->key = crypto_new_pk_env();
-     if (crypto_pk_read_private_key_from_string(tok->key, obstart))
+     if (crypto_pk_read_private_key_from_string(tok->key, obstart, eol-obstart))
        RET_ERR("Couldn't parse private key.");
    } else { /* If it's something else, try to base64-decode it */
      int r;
@@@ -4315,7 -4323,7 +4323,7 @@@ microdescs_parse_from_string(const cha
      }
  
      if ((tok = find_opt_by_keyword(tokens, K_P))) {
 -      md->exitsummary = tor_strdup(tok->args[0]);
 +      md->exit_policy = parse_short_policy(tok->args[0]);
      }
  
      crypto_digest256(md->digest, md->body, md->bodylen, DIGEST_SHA256);
diff --combined src/test/test_dir.c
index 74ea6a5,e618150..836de94
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@@ -745,11 -745,11 +745,11 @@@ test_dir_v3_networkstatus(void
    sign_skey_leg1 = pk_generate(4);
  
    test_assert(!crypto_pk_read_private_key_from_string(sign_skey_1,
-                                                       AUTHORITY_SIGNKEY_1));
+                                                       AUTHORITY_SIGNKEY_1, -1));
    test_assert(!crypto_pk_read_private_key_from_string(sign_skey_2,
-                                                       AUTHORITY_SIGNKEY_2));
+                                                       AUTHORITY_SIGNKEY_2, -1));
    test_assert(!crypto_pk_read_private_key_from_string(sign_skey_3,
-                                                       AUTHORITY_SIGNKEY_3));
+                                                       AUTHORITY_SIGNKEY_3, -1));
  
    test_assert(!crypto_pk_cmp_keys(sign_skey_1, cert1->signing_key));
    test_assert(!crypto_pk_cmp_keys(sign_skey_2, cert2->signing_key));
@@@ -800,7 -800,7 +800,7 @@@
    rs->or_port = 443;
    rs->dir_port = 8000;
    /* all flags but running cleared */
 -  rs->is_running = 1;
 +  rs->is_flagged_running = 1;
    smartlist_add(vote->routerstatus_list, vrs);
    test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
  
@@@ -815,7 -815,7 +815,7 @@@
    rs->addr = 0x99009901;
    rs->or_port = 443;
    rs->dir_port = 0;
 -  rs->is_exit = rs->is_stable = rs->is_fast = rs->is_running =
 +  rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running =
      rs->is_valid = rs->is_v2_dir = rs->is_possible_guard = 1;
    smartlist_add(vote->routerstatus_list, vrs);
    test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
@@@ -832,8 -832,7 +832,8 @@@
    rs->or_port = 400;
    rs->dir_port = 9999;
    rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
 -    rs->is_running = rs->is_valid = rs->is_v2_dir = rs->is_possible_guard = 1;
 +    rs->is_flagged_running = rs->is_valid = rs->is_v2_dir =
 +    rs->is_possible_guard = 1;
    smartlist_add(vote->routerstatus_list, vrs);
    test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
  
@@@ -1073,8 -1072,7 +1073,8 @@@
    test_assert(!rs->is_fast);
    test_assert(!rs->is_possible_guard);
    test_assert(!rs->is_stable);
 -  test_assert(rs->is_running); /* If it wasn't running it wouldn't be here */
 +  /* (If it wasn't running it wouldn't be here) */
 +  test_assert(rs->is_flagged_running);
    test_assert(!rs->is_v2_dir);
    test_assert(!rs->is_valid);
    test_assert(!rs->is_named);
@@@ -1096,7 -1094,7 +1096,7 @@@
    test_assert(rs->is_fast);
    test_assert(rs->is_possible_guard);
    test_assert(rs->is_stable);
 -  test_assert(rs->is_running);
 +  test_assert(rs->is_flagged_running);
    test_assert(rs->is_v2_dir);
    test_assert(rs->is_valid);
    test_assert(!rs->is_named);





More information about the tor-commits mailing list