[tor-commits] [torsocks/osx] Use socket rather than address to determine connection type

hoganrobert at torproject.org hoganrobert at torproject.org
Sun Oct 23 18:27:13 UTC 2011


commit c8c6c60bfb9bc9eda73a8ff400ea2fb7ca0a7f3e
Author: Robert Hogan <robert at roberthogan.net>
Date:   Sun Sep 19 13:34:02 2010 +0100

    Use socket rather than address to determine connection type
    
    In sendmsg() and sendto() we were inspecting the sock_addr_t
    structure to determine if the connection was Internet or not.
    
    Since msg->msg_name is an optional value in sendmsg() and
    sendto() this could result in crashes because we weren't ensuring
    it was non-null.
    
    Since it's optional we should have been inspecting the SO_DOMAIN
    of the connection's socket anyway - it will always be there.
    
    Part of the fix for:
    http://code.google.com/p/torsocks/issues/detail?id=15
---
 src/tsocks.c |   75 +++++++++++++++++++++++++++-------------------------------
 1 files changed, 35 insertions(+), 40 deletions(-)

diff --git a/src/tsocks.c b/src/tsocks.c
index fe2ec66..3a9327a 100644
--- a/src/tsocks.c
+++ b/src/tsocks.c
@@ -1732,9 +1732,10 @@ struct hostent *tsocks_getipnodebyname_guts(GETIPNODEBYNAME_SIGNATURE, struct ho
 
 ssize_t tsocks_sendto_guts(SENDTO_SIGNATURE, ssize_t (*original_sendto)(SENDTO_SIGNATURE))
 {
-    struct sockaddr_in *connaddr;
     int sock_type = -1;
     unsigned int sock_type_len = sizeof(sock_type);
+    int sock_domain = -1;
+    unsigned int sock_domain_len = sizeof(sock_domain);
 
     /* See comment in close() */
     if (!tsocks_init_complete) {
@@ -1749,30 +1750,26 @@ ssize_t tsocks_sendto_guts(SENDTO_SIGNATURE, ssize_t (*original_sendto)(SENDTO_S
 
     show_msg(MSGDEBUG, "Got sendto request\n");
 
-    connaddr = (struct sockaddr_in *) to;
-
-    /* Get the type of the socket */
-    getsockopt(s, SOL_SOCKET, SO_TYPE,
-      (void *) &sock_type, &sock_type_len);
+    /* Get the domain of the socket */
+    getsockopt(s, SOL_SOCKET, SO_DOMAIN,
+               (void *) &sock_domain, &sock_domain_len);
 
-    show_msg(MSGDEBUG, "sin_family: %i "
-                        "\n",
-                    connaddr->sin_family);
-
-    show_msg(MSGDEBUG, "sockopt: %i "
-                        "\n",
-                    sock_type);
-
-    /* If this isn't an INET socket we can't  */
-    /* handle it, just call the real connect now        */
-    if ((connaddr->sin_family != AF_INET)) {
-        show_msg(MSGDEBUG, "Connection isn't a TCP stream ignoring\n");
+    /* If this isn't an INET socket we can't handle it, just call the real
+       connect now */
+    if ((sock_domain != PF_INET)) {
+        show_msg(MSGDEBUG, "Connection isn't an Internet socket ignoring\n");
         return (ssize_t) original_sendto(s, buf, len, flags, to, tolen);
     }
 
 #ifdef USE_TOR_DNS
-    /* If this a UDP socket  */
-    /* then we refuse it, since it is probably a DNS request      */
+    /* Get the type of the socket */
+    getsockopt(s, SOL_SOCKET, SO_TYPE,
+               (void *) &sock_type, &sock_type_len);
+
+    show_msg(MSGDEBUG, "sockopt: %i\n",  sock_type);
+
+    /* If this a UDP socket then we refuse it, since it is probably a DNS
+       request */
     if ((sock_type != SOCK_STREAM)) {
         show_msg(MSGERR, "sendto: Connection is a UDP or ICMP stream, may be a "
                            "DNS request or other form of leak: rejecting.\n");
@@ -1786,9 +1783,10 @@ ssize_t tsocks_sendto_guts(SENDTO_SIGNATURE, ssize_t (*original_sendto)(SENDTO_S
 
 ssize_t tsocks_sendmsg_guts(SENDMSG_SIGNATURE, ssize_t (*original_sendmsg)(SENDMSG_SIGNATURE))
 {
-    struct sockaddr_in *connaddr;
     int sock_type = -1;
     unsigned int sock_type_len = sizeof(sock_type);
+    int sock_domain = -1;
+    unsigned int sock_domain_len = sizeof(sock_domain);
 
     /* See comment in close() */
     if (!tsocks_init_complete) {
@@ -1803,36 +1801,33 @@ ssize_t tsocks_sendmsg_guts(SENDMSG_SIGNATURE, ssize_t (*original_sendmsg)(SENDM
 
     show_msg(MSGDEBUG, "Got sendmsg request\n");
 
-    connaddr = (struct sockaddr_in *) msg->msg_name;
+    /* Get the domain of the socket */
+    getsockopt(s, SOL_SOCKET, SO_DOMAIN,
+               (void *) &sock_domain, &sock_domain_len);
 
-    /* Get the type of the socket */
-    getsockopt(s, SOL_SOCKET, SO_TYPE,
-      (void *) &sock_type, &sock_type_len);
-
-    show_msg(MSGDEBUG, "sin_family: %i "
-                        "\n",
-                    connaddr->sin_family);
-
-    show_msg(MSGDEBUG, "sockopt: %i "
-                        "\n",
-                    sock_type);
-
-    /* If this isn't an INET socket we can't  */
-    /* handle it, just call the real connect now        */
-    if ((connaddr->sin_family != AF_INET)) {
-        show_msg(MSGDEBUG, "Connection isn't a TCP stream ignoring\n");
+    /* If this isn't an INET socket we can't handle it, just call the real
+       connect now */
+    if ((sock_domain != PF_INET)) {
+        show_msg(MSGDEBUG, "Connection isn't an Internet socket ignoring\n");
         return (ssize_t) original_sendmsg(s, msg, flags);
     }
 
 #ifdef USE_TOR_DNS
-    /* If this a UDP socket  */
-    /* then we refuse it, since it is probably a DNS request      */
+    /* Get the type of the socket */
+    getsockopt(s, SOL_SOCKET, SO_TYPE,
+               (void *) &sock_type, &sock_type_len);
+
+    show_msg(MSGDEBUG, "sockopt: %i\n",  sock_type);
+
+    /* If this a UDP socket then we refuse it, since it is probably a DNS
+       request */
     if ((sock_type != SOCK_STREAM)) {
         show_msg(MSGERR, "sendmsg: Connection is a UDP or ICMP stream, may be a "
                            "DNS request or other form of leak: rejecting.\n");
         return -1;
     }
 #endif
+
     return (ssize_t) original_sendmsg(s, msg, flags);
 }
 





More information about the tor-commits mailing list