[tor-commits] [torsocks/master] Fix: deny connection to ANY address

dgoulet at torproject.org dgoulet at torproject.org
Fri Apr 4 22:40:27 UTC 2014


commit ebbcae0c5f6ad4772e459a80e6d99cacb731fb1f
Author: David Goulet <dgoulet at ev0ke.net>
Date:   Thu Feb 20 10:59:10 2014 +0000

    Fix: deny connection to ANY address
    
    It's possible to connect to 0.0.0.0/:: which are addresses that Tor
    can't of course handle thus deny the call and send back EINVAL.
    
    Signed-off-by: David Goulet <dgoulet at ev0ke.net>
---
 src/common/compat.h     |    2 ++
 src/common/utils.c      |   30 ++++++++++++++++++++++++++++++
 src/common/utils.h      |    1 +
 src/lib/connect.c       |    9 +++++++++
 tests/unit/test_utils.c |   38 +++++++++++++++++++++++++++++++++++++-
 5 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/src/common/compat.h b/src/common/compat.h
index ee8263f..e977b41 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -104,5 +104,7 @@ void tsocks_mutex_unlock(tsocks_mutex_t *m);
 /* Loopback address in network byte order. */
 #define TSOCKS_LOOPBACK     0x0100007f
 #define TSOCKS_LOOPBACK6    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
+#define TSOCKS_ANY          ((unsigned long int) 0x00000000)
+#define TSOCKS_ANY6         { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
 
 #endif /* TORSOCKS_COMPAT_H */
diff --git a/src/common/utils.c b/src/common/utils.c
index e526ce7..578d290 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -306,3 +306,33 @@ match:
 error:
 	return -EINVAL;
 }
+
+/*
+ * For a given sockaddr, check if the IP address is ANY which is 0.0.0.0 for
+ * IPv4 and :: for IPv6.
+ *
+ * Return 1 if it is else 0.
+ */
+ATTR_HIDDEN
+int utils_is_addr_any(const struct sockaddr *sa)
+{
+	int ret;
+
+	assert(sa);
+
+	if (sa->sa_family == AF_INET) {
+		const struct sockaddr_in *sin = (const struct sockaddr_in *) sa;
+		ret = (sin->sin_addr.s_addr == TSOCKS_ANY);
+	} else if (sa->sa_family == AF_INET6) {
+		const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *) sa;
+		const uint8_t addr[] = TSOCKS_ANY6;
+		ret = !memcmp(sin6->sin6_addr.s6_addr, addr,
+				sizeof(sin6->sin6_addr.s6_addr));
+	} else {
+		ret = 0;
+		goto end;
+	}
+
+end:
+	return ret;
+}
diff --git a/src/common/utils.h b/src/common/utils.h
index b0281eb..2f950aa 100644
--- a/src/common/utils.h
+++ b/src/common/utils.h
@@ -32,5 +32,6 @@ int utils_is_address_ipv4(const char *ip);
 int utils_is_address_ipv6(const char *ip);
 int utils_sockaddr_is_localhost(const struct sockaddr *sa);
 int utils_localhost_resolve(const char *name, int af, void *buf, size_t len);
+int utils_is_addr_any(const struct sockaddr *sa);
 
 #endif /* TORSOCKS_UTILS_H */
diff --git a/src/lib/connect.c b/src/lib/connect.c
index bb15882..e47ab38 100644
--- a/src/lib/connect.c
+++ b/src/lib/connect.c
@@ -65,6 +65,15 @@ LIBC_CONNECT_RET_TYPE tsocks_connect(LIBC_CONNECT_SIG)
 		goto error;
 	}
 
+	/*
+	 * Trying to connect to ANY address will evidently not work for Tor thus we
+	 * deny the call.
+	 */
+	if (utils_is_addr_any(addr)) {
+		errno = EINVAL;
+		goto error;
+	}
+
 	DBG("[connect] Socket family %s and type %d",
 			addr->sa_family == AF_INET ? "AF_INET" : "AF_INET6", sock_type);
 
diff --git a/tests/unit/test_utils.c b/tests/unit/test_utils.c
index 2db255b..8efa19a 100644
--- a/tests/unit/test_utils.c
+++ b/tests/unit/test_utils.c
@@ -24,7 +24,7 @@
 
 #include <tap/tap.h>
 
-#define NUM_TESTS 26
+#define NUM_TESTS 30
 
 static void test_is_address_ipv4(void)
 {
@@ -178,6 +178,41 @@ static void test_utils_tokenize_ignore_comments(void)
 	ok(nb_token == 0, "Returns 0 tokens for comment");
 }
 
+static void test_is_addr_any(void)
+{
+	int ret;
+	struct sockaddr_in sin;
+	struct sockaddr_in6 sin6;
+
+	sin.sin_family = AF_INET;
+	sin.sin_port = htons(42);
+	inet_pton(sin.sin_family, "0.0.0.0", &sin.sin_addr);
+
+	ret = utils_is_addr_any((const struct sockaddr *) &sin);
+	ok(ret == 1, "This address is 0.0.0.0");
+
+	sin.sin_family = AF_INET;
+	sin.sin_port = htons(42);
+	inet_pton(sin.sin_family, "1.0.0.0", &sin.sin_addr);
+
+	ret = utils_is_addr_any((const struct sockaddr *) &sin);
+	ok(ret == 0, "This address is NOT 0.0.0.0");
+
+	sin6.sin6_family = AF_INET6;
+	sin6.sin6_port = htons(42);
+	inet_pton(sin6.sin6_family, "::", &sin6.sin6_addr);
+
+	ret = utils_is_addr_any((const struct sockaddr *) &sin6);
+	ok(ret == 1, "This address is ::");
+
+	sin6.sin6_family = AF_INET6;
+	sin6.sin6_port = htons(42);
+	inet_pton(sin6.sin6_family, "fe80::1", &sin6.sin6_addr);
+
+	ret = utils_is_addr_any((const struct sockaddr *) &sin6);
+	ok(ret == 0, "This address is NOT ::");
+}
+
 int main(int argc, char **argv)
 {
 	/* Libtap call for the number of tests planned. */
@@ -188,6 +223,7 @@ int main(int argc, char **argv)
 	test_localhost_resolve();
 	test_sockaddr_is_localhost();
 	test_utils_tokenize_ignore_comments();
+	test_is_addr_any();
 
 	return exit_status();
 }





More information about the tor-commits mailing list