aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorteor (Tim Wilson-Brown) <teor2345@gmail.com>2016-02-26 10:53:57 +0100
committerteor (Tim Wilson-Brown) <teor2345@gmail.com>2016-02-26 10:53:57 +0100
commit8e103cb2d0d2710066e97d62a408c6ce7de49422 (patch)
treed0291e3ce1020513b24f82f23c0404e0754e40ba
parent7a782820e92cef57afcea6c6936d102d6f4512fe (diff)
downloadtor-8e103cb2d0d2710066e97d62a408c6ce7de49422.tar.gz
tor-8e103cb2d0d2710066e97d62a408c6ce7de49422.zip
Set EXCLUSIVEADDRUSE on Win32 to avoid a local port-stealing attack
-rw-r--r--changes/bug181234
-rw-r--r--src/or/connection.c33
2 files changed, 37 insertions, 0 deletions
diff --git a/changes/bug18123 b/changes/bug18123
new file mode 100644
index 0000000000..1359b4ef67
--- /dev/null
+++ b/changes/bug18123
@@ -0,0 +1,4 @@
+ o Minor bugfixes (security, win32):
+ - Set SO_EXCLUSIVEADDRUSE on Win32 to avoid a local port-stealing
+ attack.
+ Fixes bug 18123; bugfix on all tor versions. Patch by "teor".
diff --git a/src/or/connection.c b/src/or/connection.c
index 0f2b3e356e..c8fc662129 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -1061,6 +1061,31 @@ make_socket_reuseable(tor_socket_t sock)
#endif
}
+#ifdef _WIN32
+/** Tell the Windows TCP stack to prevent other applications from receiving
+ * traffic from tor's open ports. Return 0 on success, -1 on failure. */
+static int
+make_win32_socket_exclusive(tor_socket_t sock)
+{
+#ifdef SO_EXCLUSIVEADDRUSE
+ int one=1;
+
+ /* Any socket that sets REUSEADDR on win32 can bind to a port _even when
+ * somebody else already has it bound_, and _even if the original socket
+ * didn't set REUSEADDR_. Use EXCLUSIVEADDRUSE to prevent this port-stealing
+ * on win32. */
+ if (setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (void*) &one,
+ (socklen_t)sizeof(one))) {
+ return -1;
+ }
+ return 0;
+#else
+ (void) sock;
+ return 0;
+#endif
+}
+#endif
+
/** Max backlog to pass to listen. We start at */
static int listen_limit = INT_MAX;
@@ -1137,6 +1162,14 @@ connection_listener_new(const struct sockaddr *listensockaddr,
tor_socket_strerror(errno));
}
+#ifdef _WIN32
+ if (make_win32_socket_exclusive(s) < 0) {
+ log_warn(LD_NET, "Error setting SO_EXCLUSIVEADDRUSE flag on %s: %s",
+ conn_type_to_string(type),
+ tor_socket_strerror(errno));
+ }
+#endif
+
#if defined(USE_TRANSPARENT) && defined(IP_TRANSPARENT)
if (options->TransProxyType_parsed == TPT_TPROXY &&
type == CONN_TYPE_AP_TRANS_LISTENER) {