Jacek Caban : ws2_32: Avoid overflows in get_rcvsnd_timeo.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Apr 28 09:10:38 CDT 2015


Module: wine
Branch: master
Commit: 9e3a3f46fae62e758d75c8eca46c7b79f7930de7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9e3a3f46fae62e758d75c8eca46c7b79f7930de7

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Apr 27 16:00:37 2015 +0200

ws2_32: Avoid overflows in get_rcvsnd_timeo.

---

 dlls/ws2_32/socket.c | 39 +++++++++++++++++++++------------------
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 95ea83c..d6bfa94 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -1251,30 +1251,28 @@ static char *strdup_lower(const char *str)
 
 /* Utility: get the SO_RCVTIMEO or SO_SNDTIMEO socket option
  * from an fd and return the value converted to milli seconds
- * or -1 if there is an infinite time out */
-static inline int get_rcvsnd_timeo( int fd, int optname)
+ * or 0 if there is an infinite time out */
+static inline INT64 get_rcvsnd_timeo( int fd, int optname)
 {
   struct timeval tv;
   socklen_t len = sizeof(tv);
-  int ret = getsockopt(fd, SOL_SOCKET, optname, &tv, &len);
-  if( ret >= 0)
-      ret = tv.tv_sec * 1000 + tv.tv_usec / 1000;
-  if( ret <= 0 ) /* tv == {0,0} means infinite time out */
-      return -1;
-  return ret;
+  int res = getsockopt(fd, SOL_SOCKET, optname, &tv, &len);
+  if (res < 0)
+      return 0;
+  return (UINT64)tv.tv_sec * 1000 + tv.tv_usec / 1000;
 }
 
 /* macro wrappers for portability */
 #ifdef SO_RCVTIMEO
 #define GET_RCVTIMEO(fd) get_rcvsnd_timeo( (fd), SO_RCVTIMEO)
 #else
-#define GET_RCVTIMEO(fd) (-1)
+#define GET_RCVTIMEO(fd) (0)
 #endif
 
 #ifdef SO_SNDTIMEO
 #define GET_SNDTIMEO(fd) get_rcvsnd_timeo( (fd), SO_SNDTIMEO)
 #else
-#define GET_SNDTIMEO(fd) (-1)
+#define GET_SNDTIMEO(fd) (0)
 #endif
 
 /* utility: given an fd, will block until one of the events occurs */
@@ -5076,18 +5074,20 @@ static int WS2_sendto( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
         while (wsa->first_iovec < wsa->n_iovecs)
         {
             struct pollfd pfd;
-            int timeout = GET_SNDTIMEO(fd);
+            int poll_timeout = -1;
+            INT64 timeout = GET_SNDTIMEO(fd);
 
-            if (timeout != -1)
+            if (timeout)
             {
                 timeout -= GetTickCount() - timeout_start;
-                if (timeout < 0) timeout = 0;
+                if (timeout < 0) poll_timeout = 0;
+                else poll_timeout = timeout <= INT_MAX ? timeout : INT_MAX;
             }
 
             pfd.fd = fd;
             pfd.events = POLLOUT;
 
-            if (!timeout || !poll( &pfd, 1, timeout ))
+            if (!poll_timeout || !poll( &pfd, 1, poll_timeout ))
             {
                 err = WSAETIMEDOUT;
                 goto error; /* msdn says a timeout in send is fatal */
@@ -7130,18 +7130,21 @@ static int WS2_recv_base( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
         if ( is_blocking )
         {
             struct pollfd pfd;
-            int timeout = GET_RCVTIMEO(fd);
-            if (timeout != -1)
+            int poll_timeout = -1;
+            INT64 timeout = GET_RCVTIMEO(fd);
+
+            if (timeout)
             {
                 timeout -= GetTickCount() - timeout_start;
-                if (timeout < 0) timeout = 0;
+                if (timeout < 0) poll_timeout = 0;
+                else poll_timeout = timeout <= INT_MAX ? timeout : INT_MAX;
             }
 
             pfd.fd = fd;
             pfd.events = POLLIN;
             if (*lpFlags & WS_MSG_OOB) pfd.events |= POLLPRI;
 
-            if (!timeout || !poll( &pfd, 1, timeout ))
+            if (!poll_timeout || !poll( &pfd, 1, poll_timeout ))
             {
                 err = WSAETIMEDOUT;
                 /* a timeout is not fatal */




More information about the wine-cvs mailing list