Skip to content

Commit

Permalink
poll: use GetTickCount64() to avoid wrap-around issues
Browse files Browse the repository at this point in the history
The value of timeout starts as an int value, and for this reason it
cannot overflow unsigned long long aka ULONGLONG. The unsigned version
of this initial value is available in orig_timeout. The difference
(orig_timeout - elapsed) cannot wrap around because it is protected by
a conditional (as can be seen in the patch text). Hence, the ULONGLONG
difference can only have values that are smaller than the initial
timeout value and truncation to int cannot overflow.

Signed-off-by: Steve Hoelzer <[email protected]>
[j6t: improved both implementation and log message]
Signed-off-by: Johannes Sixt <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
shoelzer authored and gitster committed Nov 5, 2018
1 parent 4ede3d4 commit e8dfcac
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions compat/poll/poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
You should have received a copy of the GNU General Public License along
with this program; if not, see <http://www.gnu.org/licenses/>. */

/* To bump the minimum Windows version to Windows Vista */
#include "git-compat-util.h"

/* Tell gcc not to warn about the (nfd < 0) tests, below. */
#if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
# pragma GCC diagnostic ignored "-Wtype-limits"
Expand Down Expand Up @@ -449,7 +452,8 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
static HANDLE hEvent;
WSANETWORKEVENTS ev;
HANDLE h, handle_array[FD_SETSIZE + 2];
DWORD ret, wait_timeout, nhandles, start = 0, elapsed, orig_timeout = 0;
DWORD ret, wait_timeout, nhandles, orig_timeout = 0;
ULONGLONG start = 0;
fd_set rfds, wfds, xfds;
BOOL poll_again;
MSG msg;
Expand All @@ -465,7 +469,7 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
if (timeout != INFTIM)
{
orig_timeout = timeout;
start = GetTickCount();
start = GetTickCount64();
}

if (!hEvent)
Expand Down Expand Up @@ -614,8 +618,8 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)

if (!rc && orig_timeout && timeout != INFTIM)
{
elapsed = GetTickCount() - start;
timeout = elapsed >= orig_timeout ? 0 : orig_timeout - elapsed;
ULONGLONG elapsed = GetTickCount64() - start;
timeout = elapsed >= orig_timeout ? 0 : (int)(orig_timeout - elapsed);
}

if (!rc && timeout)
Expand Down

0 comments on commit e8dfcac

Please sign in to comment.