diff options
-rw-r--r-- | changes/bug8976 | 5 | ||||
-rw-r--r-- | src/or/circuitbuild.c | 15 | ||||
-rw-r--r-- | src/or/circuitbuild.h | 1 | ||||
-rw-r--r-- | src/or/rendservice.c | 12 |
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: |