Fix bug 889: share deep-copied keys between threads to avoid races in reference counts. Bugfix on 0.1.0.1-rc.

svn:r17672
This commit is contained in:
Nick Mathewson 2008-12-18 05:28:27 +00:00
parent 7b5be147ee
commit cebdf93949
5 changed files with 33 additions and 4 deletions

View File

@ -66,6 +66,9 @@ Changes in version 0.2.1.9-alpha - 2008-12-2?
- Clip the CircuitBuildTimeout to a minimum of 30 seconds. Warn the - Clip the CircuitBuildTimeout to a minimum of 30 seconds. Warn the
user if lower values are given in the configuration. Bugfix on user if lower values are given in the configuration. Bugfix on
0.1.1.17-rc. Patch by Sebastian. 0.1.1.17-rc. Patch by Sebastian.
- Fix a race condition when freeing keys shared between main thread
and CPU workers that could result in a memory leak. Bugfix on
0.1.0.1-rc. Fixes bug 889.
o Minor bugfixes (hidden services): o Minor bugfixes (hidden services):
- Do not throw away existing introduction points on SIGHUP; bugfix on - Do not throw away existing introduction points on SIGHUP; bugfix on

View File

@ -672,6 +672,23 @@ crypto_pk_dup_key(crypto_pk_env_t *env)
return env; return env;
} }
/** Make a real honest-to-goodness copy of <b>env</b>, and return it. */
crypto_pk_env_t *
crypto_pk_copy_full(crypto_pk_env_t *env)
{
RSA *new_key;
tor_assert(env);
tor_assert(env->key);
if (PRIVATE_KEY_OK(env)) {
new_key = RSAPrivateKey_dup(env->key);
} else {
new_key = RSAPublicKey_dup(env->key);
}
return _crypto_new_pk_env_rsa(new_key);
}
/** Encrypt <b>fromlen</b> bytes from <b>from</b> with the public key /** Encrypt <b>fromlen</b> bytes from <b>from</b> with the public key
* in <b>env</b>, using the padding method <b>padding</b>. On success, * in <b>env</b>, using the padding method <b>padding</b>. On success,
* write the result to <b>to</b>, and return the number of bytes * write the result to <b>to</b>, and return the number of bytes

View File

@ -92,6 +92,7 @@ int crypto_pk_check_key(crypto_pk_env_t *env);
int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b); int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b);
size_t crypto_pk_keysize(crypto_pk_env_t *env); size_t crypto_pk_keysize(crypto_pk_env_t *env);
crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *orig); crypto_pk_env_t *crypto_pk_dup_key(crypto_pk_env_t *orig);
crypto_pk_env_t *crypto_pk_copy_full(crypto_pk_env_t *orig);
int crypto_pk_key_is_private(const crypto_pk_env_t *key); int crypto_pk_key_is_private(const crypto_pk_env_t *key);
int crypto_pk_public_encrypt(crypto_pk_env_t *env, char *to, int crypto_pk_public_encrypt(crypto_pk_env_t *env, char *to,

View File

@ -75,8 +75,8 @@ get_onion_key(void)
return onionkey; return onionkey;
} }
/** Store a copy of the current onion key into *<b>key</b>, and a copy /** Store a full copy of the current onion key into *<b>key</b>, and a full
* of the most recent onion key into *<b>last</b>. * copy of the most recent onion key into *<b>last</b>.
*/ */
void void
dup_onion_keys(crypto_pk_env_t **key, crypto_pk_env_t **last) dup_onion_keys(crypto_pk_env_t **key, crypto_pk_env_t **last)
@ -85,9 +85,9 @@ dup_onion_keys(crypto_pk_env_t **key, crypto_pk_env_t **last)
tor_assert(last); tor_assert(last);
tor_mutex_acquire(key_lock); tor_mutex_acquire(key_lock);
tor_assert(onionkey); tor_assert(onionkey);
*key = crypto_pk_dup_key(onionkey); *key = crypto_pk_copy_full(onionkey);
if (lastonionkey) if (lastonionkey)
*last = crypto_pk_dup_key(lastonionkey); *last = crypto_pk_copy_full(lastonionkey);
else else
*last = NULL; *last = NULL;
tor_mutex_release(key_lock); tor_mutex_release(key_lock);

View File

@ -740,6 +740,14 @@ test_crypto_pk(void)
test_memeq(data1,data3,j); test_memeq(data1,data3,j);
} }
} }
/* Try copy_full */
crypto_free_pk_env(pk2);
pk2 = crypto_pk_copy_full(pk1);
test_assert(pk2 != NULL);
test_neq_ptr(pk1, pk2);
test_assert(crypto_pk_cmp_keys(pk1,pk2) == 0);
done: done:
if (pk1) if (pk1)
crypto_free_pk_env(pk1); crypto_free_pk_env(pk1);