Module: wine Branch: master Commit: 9e3a3f46fae62e758d75c8eca46c7b79f7930de7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=9e3a3f46fae62e758d75c8eca4...
Author: Jacek Caban jacek@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 */