Background:
The type, precision, and range of both time_t and clock_t are implementation defined. Local time zone and daylight savings time are also implementation defined. The Unix time standard can also vary slightly.. IE, the type of time_t and clock_t are precisely "It's a number guys!". It is therefore important to be very careful when using time_t and clock_t in C because assumptions can lead to problems ranging from errors in program timing to possible overflow from invalid type conversions. What follows are some recommendations that help one to avoid common pitfalls that cause security vulnerabilities.
Recommendation #1:
When comparing time_t, first cast the item you are comparing it with to a time_t
Traditionally, time_t is set to be a signed 32 bit integer type on Unix systems, but the C99 standard only requires that time_t is an arithmetic type. It is a common error (and temptation) to use integers interchangeably with time_t. However, doing so could lead to invalid comparisons in your code.
Non-Compliant Code
Code Block |
---|
int main(void)
{
time_t now = time(NULL);
if ( now \!= \-1 ) {
fputs(ctime(&now), stdout);
}
return 0;
}
|
The c standard mandates that time() return (time_t)(-1). Some systems may interpret (time_t)(-1) as something completely different from the integer -1. This could lead to potential invalid comparison and therefore invalid output (or worse, depending on what else is put in the if statement). Therefore the correct code is as follows:
Compliant Code
Code Block |
---|
int main(void)
{
time_t now = time(NULL);
if ( now \!= (time_t)-1 ) {
fputs(ctime(&now), stdout);
}
return 0;
}
|
In the code above the comparison will function as expected.
Recommendation #2:
Use difftime when subtracting time, and avoid other arithmetic operations when possible.
...
C99 does not define any addition functions for time; the best thing to do when you need to add time is to not. However, if you must do so, it is best to write a custom function for the platform you are on (a good place to start on ideas for structure is the difftime() function for your platform).
Recommendation #3#2:
Use proper form when subtracting clock_t's for processing time.
...
Code Block |
---|
int run_big_program() { clock_t start, finish; int seconds; start = clock(); run_long_program() finish = clock(); seconds = ((finish-start)/CLOCKS_PER_SEC); return seconds; } |
The problem here is: 1) the return values of clock() are not checked (this occurs in many implementations of this functionality) and 2) the return value seconds in inappropriate.
...
Code Block |
---|
double run_big_program () { clock_t start, finish; double seconds; start = clock(); if (start = (clock_t)(-1)){ return -1.0; } run_long_program(); finish = clock(); if (finish = (clock_t)(-1)){ return -1.0; } seconds = (double) (finish-start)/CLOCKS_PER_SEC; return seconds; } |
When appropriate one should also check for overflow in seconds.
...