git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 1/1] poll: use GetTickCount64() to avoid wrap-around issues

From
Johannes Sixt <j6t@kdbg.org>
Date
Nov 2, 2018, 16:43 UTC
Message-ID
<e8b7b173-eaa1-0fad-7e6a-771389872886@kdbg.org>
In-Reply-To
<CACbrTHctZejfDTjqWqVfPYdb=ssD253Cd2isr3BxWsL1AqsH2w@mail.gmail.com>
Am 02.11.18 um 15:47 schrieb Steve Hoelzer:
Show 26 quoted lines
> On Thu, Nov 1, 2018 at 5:22 AM Johannes Sixt <j6t@kdbg.org> wrote:
>>
>> Am 31.10.18 um 22:11 schrieb Steve Hoelzer via GitGitGadget:
>>> @@ -614,7 +618,7 @@ restart:
>>>
>>>      if (!rc && orig_timeout && timeout != INFTIM)
>>>        {
>>> -      elapsed = GetTickCount() - start;
>>> +      elapsed = (DWORD)(GetTickCount64() - start);
>>
>> AFAICS, this subtraction in the old code is the correct way to take
>> account of wrap-arounds in the tick count. The new code truncates the 64
>> bit difference to 32 bits; the result is exactly identical to a
>> difference computed from truncated 32 bit values, which is what we had
>> in the old code.
>>
>> IOW, there is no change in behavior. The statement "avoid wrap-around
>> issues" in the subject line is not correct. The patch's only effect is
>> that it removes Warning C28159.
>>
>> What is really needed is that all quantities in the calculations are
>> promoted to ULONGLONG. Unless, of course, we agree that a timeout of
>> more than 49 days cannot happen ;)
> 
> Yep, correct on all counts. I'm in favor of changing the commit message to
> only say that this patch removes Warning C28159.
How about this fixup instead?

---- 8< ---- squash! poll: use GetTickCount64() to avoid wrap-around issues

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: Johannes Sixt <j6t@kdbg.org>
---
 compat/poll/poll.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/compat/poll/poll.c b/compat/poll/poll.c
index 4abbfcb6a4..4459408c7d 100644
--- a/compat/poll/poll.c
+++ b/compat/poll/poll.c
@@ -452,7 +452,7 @@ 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, elapsed, orig_timeout = 0;
+  DWORD ret, wait_timeout, nhandles, orig_timeout = 0;
   ULONGLONG start = 0;
   fd_set rfds, wfds, xfds;
   BOOL poll_again;
@@ -618,8 +618,8 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout)
 
   if (!rc && orig_timeout && timeout != INFTIM)
     {
-      elapsed = (DWORD)(GetTickCount64() - 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)
-- 
2.19.1.406.g1aa3f475f3
Previous: Steve HoelzerNext: Steve Hoelzer
Message 5 of 17 in “Make compat/poll safer on Windows”
  1. 0/1 Make compat/poll safer on WindowsJohannes Schindelin via GitGitGadget, Oct 31, 2018
  2. 1/1 poll: use GetTickCount64() to avoid wrap-around issuesSteve Hoelzer via GitGitGadget, Oct 31, 2018
  3. Johannes SixtNov 1, 2018
  4. Steve HoelzerNov 2, 2018
  5. Johannes SixtNov 2, 2018
  6. Steve HoelzerNov 2, 2018
  7. Junio C HamanoNov 3, 2018
  8. Junio C HamanoNov 3, 2018
  9. Carlo ArenasNov 3, 2018
  10. Johannes SixtNov 3, 2018
  11. Junio C HamanoNov 4, 2018
  12. Randall S. BeckerNov 4, 2018
  13. Eric SunshineNov 5, 2018
  14. Junio C HamanoNov 5, 2018
  15. Johannes SixtNov 5, 2018
  16. Johannes SixtNov 5, 2018
  17. Johannes SchindelinNov 5, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.