Merge branch 'maint-0.2.8' into maint-0.2.9

This commit is contained in:
Nick Mathewson 2017-11-30 12:07:59 -05:00
commit 7e2b012b46
7 changed files with 53 additions and 5 deletions

5
changes/bug24313 Normal file
View File

@ -0,0 +1,5 @@
o Major bugfixes (security, hidden service v2):
- Fix a use-after-free error that could crash v2 Tor hidden services
when it failed to open circuits while expiring introductions
points. Fixes bug 24313; bugfix on 0.2.7.2-alpha. This
issue is also tracked as TROVE-2017-013 and CVE-2017-8823.

10
changes/trove-2017-009 Normal file
View File

@ -0,0 +1,10 @@
o Major bugfixes (security):
- When checking for replays in the INTRODUCE1 cell data for a (legacy)
hiddden service, correctly detect replays in the RSA-encrypted part of
the cell. We were previously checking for replays on the entire cell,
but those can be circumvented due to the malleability of Tor's legacy
hybrid encryption. This fix helps prevent a traffic confirmation
attack. Fixes bug 24244; bugfix on 0.2.4.1-alpha. This issue is also
tracked as TROVE-2017-009 and CVE-2017-8819.

8
changes/trove-2017-011 Normal file
View File

@ -0,0 +1,8 @@
o Major bugfixes (security):
- Fix a denial of service bug where an attacker could use a malformed
directory object to cause a Tor instance to pause while OpenSSL would
try to read a passphrase from the terminal. (If the terminal was not
available, tor would continue running.) Fixes bug 24246; bugfix on
every version of Tor. Also tracked as TROVE-2017-011 and
CVE-2017-8821. Found by OSS-Fuzz as testcase 6360145429790720.

View File

@ -0,0 +1,6 @@
o Major bugfixes (security, relay):
- When running as a relay, make sure that we never build a path through
ourselves, even in the case where we have somehow lost the version of
our descriptor appearing in the consensus. Fixes part of bug 21534;
bugfix on 0.2.0.1-alpha. This issue is also tracked as TROVE-2017-012
and CVE-2017-8822.

View File

@ -645,11 +645,21 @@ MOCK_IMPL(int,
return 0; return 0;
} }
/** A PEM callback that always reports a failure to get a password */
static int
pem_no_password_cb(char *buf, int size, int rwflag, void *u)
{
(void)buf;
(void)size;
(void)rwflag;
(void)u;
return 0;
}
/** Read a PEM-encoded private key from the <b>len</b>-byte string <b>s</b> /** 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, * into <b>env</b>. Return 0 on success, -1 on failure. If len is -1,
* the string is nul-terminated. * the string is nul-terminated.
*/ */
/* Used here, and used for testing. */
int int
crypto_pk_read_private_key_from_string(crypto_pk_t *env, crypto_pk_read_private_key_from_string(crypto_pk_t *env,
const char *s, ssize_t len) const char *s, ssize_t len)
@ -668,7 +678,7 @@ crypto_pk_read_private_key_from_string(crypto_pk_t *env,
if (env->key) if (env->key)
RSA_free(env->key); RSA_free(env->key);
env->key = PEM_read_bio_RSAPrivateKey(b,NULL,NULL,NULL); env->key = PEM_read_bio_RSAPrivateKey(b,NULL,pem_no_password_cb,NULL);
BIO_free(b); BIO_free(b);
@ -800,7 +810,7 @@ crypto_pk_read_public_key_from_string(crypto_pk_t *env, const char *src,
if (env->key) if (env->key)
RSA_free(env->key); RSA_free(env->key);
env->key = PEM_read_bio_RSAPublicKey(b, NULL, NULL, NULL); env->key = PEM_read_bio_RSAPublicKey(b, NULL, pem_no_password_cb, NULL);
BIO_free(b); BIO_free(b);
if (!env->key) { if (!env->key) {
crypto_log_errors(LOG_WARN, "reading public key from string"); crypto_log_errors(LOG_WARN, "reading public key from string");

View File

@ -1816,6 +1816,7 @@ rend_service_receive_introduction(origin_circuit_t *circuit,
time_t now = time(NULL); time_t now = time(NULL);
time_t elapsed; time_t elapsed;
int replay; int replay;
size_t keylen;
/* Do some initial validation and logging before we parse the cell */ /* Do some initial validation and logging before we parse the cell */
if (circuit->base_.purpose != CIRCUIT_PURPOSE_S_INTRO) { if (circuit->base_.purpose != CIRCUIT_PURPOSE_S_INTRO) {
@ -1889,9 +1890,10 @@ rend_service_receive_introduction(origin_circuit_t *circuit,
} }
/* check for replay of PK-encrypted portion. */ /* check for replay of PK-encrypted portion. */
keylen = crypto_pk_keysize(intro_key);
replay = replaycache_add_test_and_elapsed( replay = replaycache_add_test_and_elapsed(
intro_point->accepted_intro_rsa_parts, intro_point->accepted_intro_rsa_parts,
parsed_req->ciphertext, parsed_req->ciphertext_len, parsed_req->ciphertext, MIN(parsed_req->ciphertext_len, keylen),
&elapsed); &elapsed);
if (replay) { if (replay) {
@ -3849,6 +3851,10 @@ remove_invalid_intro_points(rend_service_t *service,
log_info(LD_REND, "Expiring %s as intro point for %s.", log_info(LD_REND, "Expiring %s as intro point for %s.",
safe_str_client(extend_info_describe(intro->extend_info)), safe_str_client(extend_info_describe(intro->extend_info)),
safe_str_client(service->service_id)); safe_str_client(service->service_id));
/* We might have put it in the retry list if so, undo. */
if (retry_nodes) {
smartlist_remove(retry_nodes, intro);
}
smartlist_add(service->expiring_nodes, intro); smartlist_add(service->expiring_nodes, intro);
SMARTLIST_DEL_CURRENT(service->intro_nodes, intro); SMARTLIST_DEL_CURRENT(service->intro_nodes, intro);
/* Intro point is expired, we need a new one thus don't consider it /* Intro point is expired, we need a new one thus don't consider it

View File

@ -2829,7 +2829,10 @@ router_choose_random_node(smartlist_t *excludedsmartlist,
}); });
} }
if ((r = routerlist_find_my_routerinfo())) /* If the node_t is not found we won't be to exclude ourself but we
* won't be able to pick ourself in router_choose_random_node() so
* this is fine to at least try with our routerinfo_t object. */
if ((r = router_get_my_routerinfo()))
routerlist_add_node_and_family(excludednodes, r); routerlist_add_node_and_family(excludednodes, r);
router_add_running_nodes_to_smartlist(sl, allow_invalid, router_add_running_nodes_to_smartlist(sl, allow_invalid,