summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changes/bug89765
-rw-r--r--src/or/circuitbuild.c15
-rw-r--r--src/or/circuitbuild.h1
-rw-r--r--src/or/rendservice.c12
4 files changed, 33 insertions, 0 deletions
diff --git a/changes/bug8976 b/changes/bug8976
new file mode 100644
index 0000000000..ff1c1a7ae4
--- /dev/null
+++ b/changes/bug8976
@@ -0,0 +1,5 @@
+ o Minor bugfixes (security, hidden services):
+ - Prevent hidden services connecting to client-supplied rendezvous
+ addresses that are reserved as internal or multicast.
+ Fixes bug 8976; bugfix on b7c172c9e in tor-0.2.3.21.
+ Patch by "dgoulet" and "teor".
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index baa7bad2e6..a15f4c28b5 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -2419,3 +2419,18 @@ build_state_get_exit_nickname(cpath_build_state_t *state)
return state->chosen_exit->nickname;
}
+/** Return true iff the given address can be used to extend to. */
+int extend_info_addr_is_allowed(const tor_addr_t *addr)
+{
+ tor_assert(addr);
+
+ /* Check if we have a private address and if we can extend to it. */
+ if ((tor_addr_is_internal(addr, 0) || tor_addr_is_multicast(addr)) &&
+ !get_options()->ExtendAllowPrivateAddresses) {
+ goto disallow;
+ }
+ /* Allowed! */
+ return 1;
+ disallow:
+ return 0;
+}
diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h
index e9c1d77d94..7f5fd511a9 100644
--- a/src/or/circuitbuild.h
+++ b/src/or/circuitbuild.h
@@ -53,6 +53,7 @@ extend_info_t *extend_info_new(const char *nickname, const char *digest,
extend_info_t *extend_info_from_node(const node_t *r, int for_direct_connect);
extend_info_t *extend_info_dup(extend_info_t *info);
void extend_info_free(extend_info_t *info);
+int extend_info_addr_is_allowed(const tor_addr_t *addr);
const node_t *build_state_get_exit_node(cpath_build_state_t *state);
const char *build_state_get_exit_nickname(cpath_build_state_t *state);
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index e9a6c9df31..09b20e34a4 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -1818,6 +1818,18 @@ find_rp_for_intro(const rend_intro_cell_t *intro,
goto err;
}
+ /* Make sure the RP we are being asked to connect to is _not_ a private
+ * address unless it's allowed. Let's avoid to build a circuit to our
+ * second middle node and fail right after when extending to the RP. */
+ if (!extend_info_addr_is_allowed(&rp->addr)) {
+ if (err_msg_out) {
+ tor_asprintf(&err_msg,
+ "Relay IP in INTRODUCE2 cell is private address.");
+ }
+ extend_info_free(rp);
+ rp = NULL;
+ goto err;
+ }
goto done;
err: