summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2012-10-19 14:30:31 -0400
committerNick Mathewson <nickm@torproject.org>2012-10-19 14:30:31 -0400
commit1cc06bd35e4203569ecc72ff314a1dd543f60651 (patch)
treeb76e1b771640fdd30788dff3be9492c84494e440
parentb6931b010512d3d8cbda24c87a8cf379305e1457 (diff)
parentf357ef9dccccfb5ce2408dbd5f8456de02bac895 (diff)
downloadtor-1cc06bd35e4203569ecc72ff314a1dd543f60651.tar.gz
tor-1cc06bd35e4203569ecc72ff314a1dd543f60651.zip
Merge branch 'block_renegotiate_023' into maint-0.2.3
-rw-r--r--changes/cve-2012-22495
-rw-r--r--src/or/command.c1
-rw-r--r--src/or/connection_or.c14
-rw-r--r--src/or/connection_or.h1
4 files changed, 19 insertions, 2 deletions
diff --git a/changes/cve-2012-2249 b/changes/cve-2012-2249
new file mode 100644
index 0000000000..625bfa2f58
--- /dev/null
+++ b/changes/cve-2012-2249
@@ -0,0 +1,5 @@
+ o Major bugfixes (security):
+ - Discard extraneous renegotiation attempts once the V3 link
+ protocol has been initiated. Failure to do so left us open to
+ a remotely triggerable assertion failure. Fixes CVE-2012-2249;
+ bugfix on 0.2.3.6-alpha. Reported by "some guy from France".
diff --git a/src/or/command.c b/src/or/command.c
index d8a409bc27..975af046cd 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -649,6 +649,7 @@ enter_v3_handshake_with_cell(var_cell_t *cell, or_connection_t *conn)
"Received a cell while TLS-handshaking, not in "
"OR_HANDSHAKING_V3, on a connection we originated.");
}
+ connection_or_block_renegotiation(conn);
conn->_base.state = OR_CONN_STATE_OR_HANDSHAKING_V3;
if (connection_init_or_handshake_state(conn, started_here) < 0) {
connection_mark_for_close(TO_CONN(conn));
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index d016387935..6293fe881d 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -1186,6 +1186,17 @@ connection_tls_start_handshake(or_connection_t *conn, int receiving)
return 0;
}
+/** Block all future attempts to renegotiate on 'conn' */
+void
+connection_or_block_renegotiation(or_connection_t *conn)
+{
+ tor_tls_t *tls = conn->tls;
+ if (!tls)
+ return;
+ tor_tls_set_renegotiate_callback(tls, NULL, NULL);
+ tor_tls_block_renegotiation(tls);
+}
+
/** Invoked on the server side from inside tor_tls_read() when the server
* gets a successful TLS renegotiation from the client. */
static void
@@ -1195,8 +1206,7 @@ connection_or_tls_renegotiated_cb(tor_tls_t *tls, void *_conn)
(void)tls;
/* Don't invoke this again. */
- tor_tls_set_renegotiate_callback(tls, NULL, NULL);
- tor_tls_block_renegotiation(tls);
+ connection_or_block_renegotiation(conn);
if (connection_tls_finish_handshake(conn) < 0) {
/* XXXX_TLS double-check that it's ok to do this from inside read. */
diff --git a/src/or/connection_or.h b/src/or/connection_or.h
index 3e98f5cce1..b78c444921 100644
--- a/src/or/connection_or.h
+++ b/src/or/connection_or.h
@@ -21,6 +21,7 @@ or_connection_t *connection_or_get_for_extend(const char *digest,
int *launch_out);
void connection_or_set_bad_connections(const char *digest, int force);
+void connection_or_block_renegotiation(or_connection_t *conn);
int connection_or_reached_eof(or_connection_t *conn);
int connection_or_process_inbuf(or_connection_t *conn);
int connection_or_flushed_some(or_connection_t *conn);