mirror of
https://github.com/moparisthebest/curl
synced 2025-01-11 05:58:01 -05:00
select: add overflow checks for timeval conversions
Using time_t and suseconds_t if suseconds_t is available, long on Windows (maybe others in the future) and int elsewhere. Also handle case of ULONG_MAX being greater or equal to INFINITE. Assisted-by: Jay Satiro Reviewed-by: Daniel Stenberg Part of #5343
This commit is contained in:
parent
4a8f459837
commit
fc55c723c4
13
configure.ac
13
configure.ac
@ -4064,6 +4064,19 @@ AC_CHECK_TYPE(sa_family_t,
|
||||
#endif
|
||||
])
|
||||
|
||||
# check for suseconds_t
|
||||
AC_CHECK_TYPE([suseconds_t],[
|
||||
AC_DEFINE(HAVE_SUSECONDS_T, 1,
|
||||
[Define to 1 if suseconds_t is an available type.])
|
||||
], ,[
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([if time_t is unsigned])
|
||||
CURL_RUN_IFELSE(
|
||||
[
|
||||
|
63
lib/select.c
63
lib/select.c
@ -90,7 +90,12 @@ int Curl_wait_ms(timediff_t timeout_ms)
|
||||
/* prevent overflow, timeout_ms is typecast to ULONG/DWORD. */
|
||||
#if TIMEDIFF_T_MAX > ULONG_MAX
|
||||
if(timeout_ms > ULONG_MAX)
|
||||
#if ULONG_MAX < INFINITE
|
||||
timeout_ms = ULONG_MAX;
|
||||
#else
|
||||
timeout_ms = ULONG_MAX-1;
|
||||
/* avoid waiting forever */
|
||||
#endif
|
||||
#endif
|
||||
Sleep((ULONG)timeout_ms);
|
||||
#else
|
||||
@ -104,8 +109,33 @@ int Curl_wait_ms(timediff_t timeout_ms)
|
||||
#else
|
||||
{
|
||||
struct timeval pending_tv;
|
||||
pending_tv.tv_sec = timeout_ms / 1000;
|
||||
pending_tv.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
timediff_t tv_sec = timeout_ms / 1000;
|
||||
timediff_t tv_usec = (timeout_ms % 1000) * 1000; /* max=999999 */
|
||||
#ifdef HAVE_SUSECONDS_T
|
||||
#if TIMEDIFF_T_MAX > TIME_T_MAX
|
||||
/* tv_sec overflow check in case time_t is signed */
|
||||
if(tv_sec > TIME_T_MAX)
|
||||
tv_sec = TIME_T_MAX;
|
||||
#endif
|
||||
pending_tv.tv_sec = (time_t)tv_sec;
|
||||
pending_tv.tv_usec = (suseconds_t)tv_usec;
|
||||
#elif defined(WIN32) /* maybe also others in the future */
|
||||
#if TIMEDIFF_T_MAX > LONG_MAX
|
||||
/* tv_sec overflow check on Windows there we know it is long */
|
||||
if(tv_sec > LONG_MAX)
|
||||
tv_sec = LONG_MAX;
|
||||
#endif
|
||||
pending_tv.tv_sec = (long)tv_sec;
|
||||
pending_tv.tv_usec = (long)tv_usec;
|
||||
#else
|
||||
#if TIMEDIFF_T_MAX > INT_MAX
|
||||
/* tv_sec overflow check in case time_t is signed */
|
||||
if(tv_sec > INT_MAX)
|
||||
tv_sec = INT_MAX;
|
||||
#endif
|
||||
pending_tv.tv_sec = (int)tv_sec;
|
||||
pending_tv.tv_usec = (int)tv_usec;
|
||||
#endif
|
||||
r = select(0, NULL, NULL, NULL, &pending_tv);
|
||||
}
|
||||
#endif /* HAVE_POLL_FINE */
|
||||
@ -151,8 +181,33 @@ int Curl_select(curl_socket_t maxfd, /* highest socket number */
|
||||
ptimeout = NULL;
|
||||
}
|
||||
else if(timeout_ms > 0) {
|
||||
pending_tv.tv_sec = timeout_ms / 1000;
|
||||
pending_tv.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
timediff_t tv_sec = timeout_ms / 1000;
|
||||
timediff_t tv_usec = (timeout_ms % 1000) * 1000; /* max=999999 */
|
||||
#ifdef HAVE_SUSECONDS_T
|
||||
#if TIMEDIFF_T_MAX > TIME_T_MAX
|
||||
/* tv_sec overflow check in case time_t is signed */
|
||||
if(tv_sec > TIME_T_MAX)
|
||||
tv_sec = TIME_T_MAX;
|
||||
#endif
|
||||
pending_tv.tv_sec = (time_t)tv_sec;
|
||||
pending_tv.tv_usec = (suseconds_t)tv_usec;
|
||||
#elif defined(WIN32) /* maybe also others in the future */
|
||||
#if TIMEDIFF_T_MAX > LONG_MAX
|
||||
/* tv_sec overflow check on Windows there we know it is long */
|
||||
if(tv_sec > LONG_MAX)
|
||||
tv_sec = LONG_MAX;
|
||||
#endif
|
||||
pending_tv.tv_sec = (long)tv_sec;
|
||||
pending_tv.tv_usec = (long)tv_usec;
|
||||
#else
|
||||
#if TIMEDIFF_T_MAX > INT_MAX
|
||||
/* tv_sec overflow check in case time_t is signed */
|
||||
if(tv_sec > INT_MAX)
|
||||
tv_sec = INT_MAX;
|
||||
#endif
|
||||
pending_tv.tv_sec = (int)tv_sec;
|
||||
pending_tv.tv_usec = (int)tv_usec;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
pending_tv.tv_sec = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user