From 736286f36c61893197ae5554d010fcb068225270 Mon Sep 17 00:00:00 2001
From: Marc Hoersken <info@marc-hoersken.de>
Date: Mon, 11 Jun 2012 17:10:19 +0200
Subject: [PATCH] connect.c/ftp.c: Fixed dereferencing pointer breakin
 strict-aliasing

---
 lib/connect.c |   38 +++++++++++++++++++-------------------
 lib/ftp.c     |   44 ++++++++++++++++++++++----------------------
 2 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/lib/connect.c b/lib/connect.c
index 28c1019..352dcf4 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -256,13 +256,13 @@ static CURLcode bindlocal(struct connectdata *conn,
   curl_socklen_t sizeof_sa = 0; /* size of the data sock points to */
 
   union sockaddr_u {
-    struct sockaddr sa;
-    struct sockaddr_in sa4;
+    struct sockaddr *sa;
+    struct sockaddr_in *sa4;
 #ifdef ENABLE_IPV6
-    struct sockaddr_in6 sa6;
+    struct sockaddr_in6 *sa6;
 #endif
-  };
-  union sockaddr_u *sock = (union sockaddr_u *)&sa; /* bind to this address */
+  } sock;
+  sock.sa = (struct sockaddr *)&sa; /* bind to this address */
 
   struct Curl_dns_entry *h=NULL;
   unsigned short port = data->set.localport; /* use this port number, 0 for
@@ -377,18 +377,18 @@ static CURLcode bindlocal(struct connectdata *conn,
 #ifdef ENABLE_IPV6
       /* ipv6 address */
       if((af == AF_INET6) &&
-         (Curl_inet_pton(AF_INET6, myhost, &sock->sa6.sin6_addr) > 0)) {
-        sock->sa6.sin6_family = AF_INET6;
-        sock->sa6.sin6_port = htons(port);
+         (Curl_inet_pton(AF_INET6, myhost, &sock.sa6->sin6_addr) > 0)) {
+        sock.sa6->sin6_family = AF_INET6;
+        sock.sa6->sin6_port = htons(port);
         sizeof_sa = sizeof(struct sockaddr_in6);
       }
       else
 #endif
       /* ipv4 address */
       if((af == AF_INET) &&
-         (Curl_inet_pton(AF_INET, myhost, &sock->sa4.sin_addr) > 0)) {
-        sock->sa4.sin_family = AF_INET;
-        sock->sa4.sin_port = htons(port);
+         (Curl_inet_pton(AF_INET, myhost, &sock.sa4->sin_addr) > 0)) {
+        sock.sa4->sin_family = AF_INET;
+        sock.sa4->sin_port = htons(port);
         sizeof_sa = sizeof(struct sockaddr_in);
       }
     }
@@ -402,21 +402,21 @@ static CURLcode bindlocal(struct connectdata *conn,
     /* no device was given, prepare sa to match af's needs */
 #ifdef ENABLE_IPV6
     if(af == AF_INET6) {
-      sock->sa6.sin6_family = AF_INET6;
-      sock->sa6.sin6_port = htons(port);
+      sock.sa6->sin6_family = AF_INET6;
+      sock.sa6->sin6_port = htons(port);
       sizeof_sa = sizeof(struct sockaddr_in6);
     }
     else
 #endif
     if(af == AF_INET) {
-      sock->sa4.sin_family = AF_INET;
-      sock->sa4.sin_port = htons(port);
+      sock.sa4->sin_family = AF_INET;
+      sock.sa4->sin_port = htons(port);
       sizeof_sa = sizeof(struct sockaddr_in);
     }
   }
 
   for(;;) {
-    if(bind(sockfd, &sock->sa, sizeof_sa) >= 0) {
+    if(bind(sockfd, sock.sa, sizeof_sa) >= 0) {
       /* we succeeded to bind */
       struct Curl_sockaddr_storage add;
       curl_socklen_t size = sizeof(add);
@@ -436,11 +436,11 @@ static CURLcode bindlocal(struct connectdata *conn,
       infof(data, "Bind to local port %hu failed, trying next\n", port);
       port++; /* try next port */
       /* We re-use/clobber the port variable here below */
-      if(sock->sa.sa_family == AF_INET)
-        sock->sa4.sin_port = ntohs(port);
+      if(sock.sa->sa_family == AF_INET)
+        sock.sa4->sin_port = ntohs(port);
 #ifdef ENABLE_IPV6
       else
-        sock->sa6.sin6_port = ntohs(port);
+        sock.sa6->sin6_port = ntohs(port);
 #endif
     }
     else
diff --git a/lib/ftp.c b/lib/ftp.c
index cb952db..7cbef25 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -956,13 +956,13 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
 
   struct Curl_sockaddr_storage ss;
   union sockaddr_u {
-    struct sockaddr sa;
-    struct sockaddr_in sa4;
+    struct sockaddr *sa;
+    struct sockaddr_in *sa4;
 #ifdef ENABLE_IPV6
-    struct sockaddr_in6 sa6;
+    struct sockaddr_in6 *sa6;
 #endif
-  };
-  union sockaddr_u *sock = (union sockaddr_u *)&ss;
+  } sock;
+  sock.sa = (struct sockaddr *)&ss;
 
   Curl_addrinfo *res, *ai;
   curl_socklen_t sslen;
@@ -1021,7 +1021,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
     else if((ip_end = strchr(string_ftpport, ':')) != NULL) {
         /* either ipv6 or (ipv4|domain|interface):port(-range) */
 #ifdef ENABLE_IPV6
-      if(Curl_inet_pton(AF_INET6, string_ftpport, &sock->sa6) == 1) {
+      if(Curl_inet_pton(AF_INET6, string_ftpport, sock.sa6) == 1) {
         /* ipv6 */
         port_min = port_max = 0;
         strcpy(addr, string_ftpport);
@@ -1077,21 +1077,21 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
        the IP from the control connection */
 
     sslen = sizeof(ss);
-    if(getsockname(conn->sock[FIRSTSOCKET], &sock->sa, &sslen)) {
+    if(getsockname(conn->sock[FIRSTSOCKET], sock.sa, &sslen)) {
       failf(data, "getsockname() failed: %s",
           Curl_strerror(conn, SOCKERRNO) );
       Curl_safefree(addr);
       return CURLE_FTP_PORT_FAILED;
     }
-    switch(sock->sa.sa_family) {
+    switch(sock.sa->sa_family) {
 #ifdef ENABLE_IPV6
     case AF_INET6:
-      Curl_inet_ntop(sock->sa.sa_family, &sock->sa6.sin6_addr, hbuf,
+      Curl_inet_ntop(sock.sa->sa_family, &sock.sa6->sin6_addr, hbuf,
                      sizeof(hbuf));
       break;
 #endif
     default:
-      Curl_inet_ntop(sock->sa.sa_family, &sock->sa4.sin_addr, hbuf,
+      Curl_inet_ntop(sock.sa->sa_family, &sock.sa4->sin_addr, hbuf,
                      sizeof(hbuf));
       break;
     }
@@ -1140,18 +1140,18 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
 
   /* step 3, bind to a suitable local address */
 
-  memcpy(&sock->sa, ai->ai_addr, ai->ai_addrlen);
+  memcpy(sock.sa, ai->ai_addr, ai->ai_addrlen);
   sslen = ai->ai_addrlen;
 
   for(port = port_min; port <= port_max;) {
-    if(sock->sa.sa_family == AF_INET)
-      sock->sa4.sin_port = htons(port);
+    if(sock.sa->sa_family == AF_INET)
+      sock.sa4->sin_port = htons(port);
 #ifdef ENABLE_IPV6
     else
-      sock->sa6.sin6_port = htons(port);
+      sock.sa6->sin6_port = htons(port);
 #endif
     /* Try binding the given address. */
-    if(bind(portsock, &sock->sa, sslen) ) {
+    if(bind(portsock, sock.sa, sslen) ) {
       /* It failed. */
       error = SOCKERRNO;
       if(possibly_non_local && (error == EADDRNOTAVAIL)) {
@@ -1163,7 +1163,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
               Curl_strerror(conn, error) );
 
         sslen = sizeof(ss);
-        if(getsockname(conn->sock[FIRSTSOCKET], &sock->sa, &sslen)) {
+        if(getsockname(conn->sock[FIRSTSOCKET], sock.sa, &sslen)) {
           failf(data, "getsockname() failed: %s",
                 Curl_strerror(conn, SOCKERRNO) );
           Curl_closesocket(conn, portsock);
@@ -1196,7 +1196,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
   /* get the name again after the bind() so that we can extract the
      port number it uses now */
   sslen = sizeof(ss);
-  if(getsockname(portsock, (struct sockaddr *)&sock->sa, &sslen)) {
+  if(getsockname(portsock, (struct sockaddr *)sock.sa, &sslen)) {
     failf(data, "getsockname() failed: %s",
           Curl_strerror(conn, SOCKERRNO) );
     Curl_closesocket(conn, portsock);
@@ -1230,17 +1230,17 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
       /* if disabled, goto next */
       continue;
 
-    if((PORT == fcmd) && sock->sa.sa_family != AF_INET)
+    if((PORT == fcmd) && sock.sa->sa_family != AF_INET)
       /* PORT is ipv4 only */
       continue;
 
-    switch (sock->sa.sa_family) {
+    switch (sock.sa->sa_family) {
     case AF_INET:
-      port = ntohs(sock->sa4.sin_port);
+      port = ntohs(sock.sa4->sin_port);
       break;
 #ifdef ENABLE_IPV6
     case AF_INET6:
-      port = ntohs(sock->sa6.sin6_port);
+      port = ntohs(sock.sa6->sin6_port);
       break;
 #endif
     default:
@@ -1257,7 +1257,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
        */
 
       result = Curl_pp_sendf(&ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd],
-                             sock->sa.sa_family == AF_INET?1:2,
+                             sock.sa->sa_family == AF_INET?1:2,
                              myhost, port);
       if(result) {
         failf(data, "Failure sending EPRT command: %s",
-- 
1.7.10.msysgit.1

