You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by hi...@apache.org on 2010/06/08 08:05:18 UTC

svn commit: r952544 - /harmony/enhanced/java/trunk/classlib/modules/portlib/src/main/native/port/unix/hysock.c

Author: hindessm
Date: Tue Jun  8 06:05:18 2010
New Revision: 952544

URL: http://svn.apache.org/viewvc?rev=952544&view=rev
Log:
Fixing length arguments passed to socket syscalls.  The lengths are
lengths of the sock storage and they should be derived from the address
*not* the socket.  If you derive them from the socket then you will
do invalid reads if the socket is IPv6 and the address is (shorter) IPv4.
Linux doesn't seem to care much about these but FreeBSD does.

Modified:
    harmony/enhanced/java/trunk/classlib/modules/portlib/src/main/native/port/unix/hysock.c

Modified: harmony/enhanced/java/trunk/classlib/modules/portlib/src/main/native/port/unix/hysock.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/portlib/src/main/native/port/unix/hysock.c?rev=952544&r1=952543&r2=952544&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/portlib/src/main/native/port/unix/hysock.c (original)
+++ harmony/enhanced/java/trunk/classlib/modules/portlib/src/main/native/port/unix/hysock.c Tue Jun  8 06:05:18 2010
@@ -131,6 +131,8 @@ I_32 map_sockettype_Hy_to_OS (I_32 socke
 
 static I_32 findHostError (int herr);
 
+static socklen_t getAddrLength(hysockaddr_t addr);
+
 #undef CDEV_CURRENT_FUNCTION
 
 #if NO_R
@@ -593,22 +595,7 @@ hysock_bind (struct HyPortLibrary * port
              hysockaddr_t addr)
 {
   I_32 rc = 0;
-  I_32 length = sizeof (addr->addr);
-
-#if defined(SIN6_LEN)
-  length = sizeof (struct sockaddr_storage);
-#if defined(IPv6_FUNCTION_SUPPORT)
-  if (((OSSOCKADDR *) & addr->addr)->sin_family == OS_AF_INET6)
-    {
-      length = ((OSSOCKADDR_IN6 *) & addr->addr)->sin6_len;
-    }
-#if defined(FREEBSD)
-  else {
-    length = ((OSSOCKADDR *) & addr->addr)->sin_len;
-  }
-#endif
-#endif
-#endif
+  I_32 length = getAddrLength(addr);
 
   if (bind
       (SOCKET_CAST (sock), (struct sockaddr *) &addr->addr, length) < 0)
@@ -682,12 +669,7 @@ hysock_connect (struct HyPortLibrary * p
                 hysockaddr_t addr)
 {
   I_32 rc = 0;
-  I_32 length =
-#if !defined(FREEBSD)
-           sizeof (addr->addr);
-#else
-           ((OSSOCKADDR *) & addr->addr)->sin_len;
-#endif
+  I_32 length = getAddrLength(addr);
 
   if (connect
       (SOCKET_CAST (sock), (struct sockaddr *) &addr->addr, length) < 0)
@@ -2067,7 +2049,7 @@ I_32 VMCALL
 hysock_getpeername (struct HyPortLibrary * portLibrary, hysocket_t handle,
                     hysockaddr_t addrHandle)
 {
-  socklen_t addrlen = sizeof (addrHandle->addr);
+  socklen_t addrlen = getAddrLength(addrHandle);
 
   if (getpeername
       (SOCKET_CAST (handle), (struct sockaddr *) &addrHandle->addr,
@@ -2559,7 +2541,7 @@ hysock_readfrom (struct HyPortLibrary * 
 
   if (NULL == addrHandle)
     {
-      addrlen = sizeof (*addrHandle);
+      addrlen = sizeof (*addrHandle); /* TOFIX: This is not used? */
       bytesRec =
         recvfrom (SOCKET_CAST (sock), buf, nbyte, flags, NULL, &addrlen);
     }
@@ -2569,6 +2551,7 @@ hysock_readfrom (struct HyPortLibrary * 
       bytesRec =
         recvfrom (SOCKET_CAST (sock), buf, nbyte, flags,
                   (struct sockaddr *) &addrHandle->addr, &addrlen);
+      /* TOFIX: should check if addrlen > sizeof(addrlen) ? */
     }
   if (bytesRec == -1)
     {
@@ -3575,11 +3558,6 @@ hysock_sockaddr_init6 (struct HyPortLibr
       sockaddr_6->sin6_flowinfo = htonl (flowinfo);
 #if defined(SIN6_LEN)
       sockaddr_6->sin6_len = sizeof(OSSOCKADDR_IN6);
-      if (((OSSOCKADDR_IN6 *) & handle->addr)->sin6_len != 0)
-        {
-          sockaddr_6->sin6_len =
-            ((OSSOCKADDR_IN6 *) & handle->addr)->sin6_len;
-        }
 #endif
     }
 #endif
@@ -3591,7 +3569,7 @@ hysock_sockaddr_init6 (struct HyPortLibr
       sockaddr->sin_port = nPort;
       sockaddr->sin_family = map_addr_family_Hy_to_OS (family);
 #if defined(FREEBSD)
-          sockaddr->sin_len = sizeof(OSSOCKADDR);
+      sockaddr->sin_len = sizeof(OSSOCKADDR);
 #endif
     }
 
@@ -3867,7 +3845,7 @@ hysock_writeto (struct HyPortLibrary * p
   bytesSent =
     sendto (SOCKET_CAST (sock), buf, nbyte, flags,
             (struct sockaddr *) &(addrHandle->addr),
-            sizeof (addrHandle->addr));
+            getAddrLength(addrHandle));
 
   if (bytesSent == -1)
     {
@@ -5188,7 +5166,7 @@ hysock_connect_with_timeout (struct HyPo
 
       rc = connect
           (SOCKET_CAST (sock), (struct sockaddr *) &addr->addr,
-           sizeof (addr->addr));
+           getAddrLength(addr));
       if (rc < 0)
         {
           rc = errno;
@@ -5296,6 +5274,15 @@ hysock_connect_with_timeout (struct HyPo
 
 #undef CDEV_CURRENT_FUNCTION
 
-#define CDEV_CURRENT_FUNCTION
+#define CDEV_CURRENT_FUNCTION getAddrLength
 
+static socklen_t getAddrLength(hysockaddr_t addr)
+{
+  return
+#if defined(IPv6_FUNCTION_SUPPORT)
+    ((OSSOCKADDR *) & addr->addr)->sin_family == OS_AF_INET6 ?
+    sizeof(OSSOCKADDR_IN6) :
+#endif
+    sizeof(OSSOCKADDR);
+}
 #undef CDEV_CURRENT_FUNCTION