Nmap Development mailing list archives

Re: Timeval subtraction coolest bug


From: David Fifield <david () bamsoftware com>
Date: Thu, 16 Jul 2009 10:54:00 -0600

On Thu, Jul 16, 2009 at 06:51:48PM +0300, ithilgore wrote:
I am writing this, since I came across some bizarre behaviour with
Ncrack. The problem is that starting from today, the unix epoch
seconds and microseconds returned from gettimeofday() into a timeval
struct in combination with some multiplication, can get too large for
a long variable to hold them.

Ncrack, like Nmap, uses some macros to make subtractions between
timeval structs:

/* Timeval subtract in milliseconds */
#define TIMEVAL_MSEC_SUBTRACT(a,b) ((((a).tv_sec - (b).tv_sec) * 1000) +
((a).tv_usec - (b).tv_usec) / 1000)

Now the problem is that if the b timeval struct is just a struct
initialized with 0 (which can happen) then the first subtraction
equals: a.tv_sec * 1000. The fact that a long number (tv_sec and
tv_usec are long numbers) is multiplied by 1000, can get us a wrap
around, if that long number is big enough (which seems to be the case
from today). Add to that the addition of the microseconds in the
second part of the equation and the chances of a wrap-around increase.
The wrap-around means that the returned long number is now a negative
number.

At first I wondered, what's so special about today? Right now the
timestamp is 1247762431, which when multiplied by 1000 is 0x122846fbc18,
so it has been overflowing for a long time. But then I saw that the
low-order 32 bits are 0x846fbc18, which is negative. And in fact, it has
only been since yesterday that that is the case:

$ python
import datetime
print datetime.datetime.fromtimestamp(0x12280000000 / 1000.)
2009-07-15 13:59:59.488000

That's pretty interesting! But it will cycle between positive and
negative every 0x80000000 / 1000 seconds, or about every 24 days. Don't
worry, it will be non-negative again on 2009-08-09 10:31:23.136000.

We ran into these overflow problems before. If you're just checking if
one date is after another, use the TIMEVAL_BEFORE and TIMEVAL_AFTER
macros instead of subtracting and checking the sign of the difference.

Good find!

David Fifield

_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org


Current thread: