Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The type , precision, and range of clock_t are implementation defined. time_t is specified as an "arithmetic type capable of representing times." as size_t, which is "an unsigned integer type", but how time is encoding within the arithmetic type is unspecified.

Computing Time Passed

Non-Compliant Code Example

However, the way time is encoded within this arithmetic type by the function time() is unspecified. See unspecified behavior 48 in Annex J of the C Standard. Because the encoding is unspecified, there is no safe way to manually perform arithmetic on the type, and as a result, the values should not be modified directly.

Note that POSIX specifies that the time() function must return a value of type time_t, representing time in seconds since the Epoch. POSIX-conforming applications that are not intended to be portable to other environments therefore may safely perform arithmetic operations on time_t objects.

Noncompliant Code Example

This noncompliant code example attempts to execute doThis code attempts to execute do_some_work() multiple times until at least seconds_to_work has passed. However, because the encoding is not defined, there is no guarantee that adding start to seconds_to_work will result in adding seconds_to_work seconds.

Code Block
bgColor#FFCCCC
langc

int do_work(int seconds_to_work) {
  time_t start;
  start = time(NULL);

  if (start == (time_t)(-1)) {
    /* Handle error */
  }
  while (time(NULL) < start + secondseconds_to_work) {
    do_some_work();/* ... */
  }
  return 0;
}

Compliant

...

Solution

The This compliant code example solution uses difftime() to determine the difference between two time_t values. The difftime() function returns the number of seconds, from the second parameter until the first parameter and returns the result, as a double.

Code Block
bgColor#ccccff
langc

int do_work(int seconds_to_work) {
  time_t start, current = time(NULL);
  time_t startcurrent = time()start;

  if (start == (time_t)(-1)) {
    /* Handle error */
  }
  while (timedifftime(current, start) < start + secondseconds_to_work) {
    current = time(NULL);
    if (current == (time_t)(-1)) {
       /* Handle error */
    }
    if (difftime(current, start) >= seconds_to_work)
      break;/* ... */
  }
    do_some_work();
  }return 0;
}

Note that this loop may still might not exit , as because the range of time_t may might not be able to represent two times seconds_to_work apart.

Compute time in the future or past

This section is incomplete

Risk Assessment

Using time_t incorrectly can lead to broken logic that can place a program in an infinite loop or cause an expected logic branch to not execute.

Recommendation Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MSC05-A

5

2

2

P6

L2

References

- The original idea for this came from the C Language Gotchas site, accessible here

- The wikipedia article on Unix Time is quite enlightening. Read it here

- An article about a denial-of-service in 64bit microsoft time code. Read it here 

C

Low

Unlikely

Medium

P2

L3

Automated Detection

Tool

Version

Checker

Description

Compass/ROSE

 

 

Can detect violations of this recommendation

ECLAIR

Include Page
ECLAIR_V
ECLAIR_V

CC2.MSC05

Fully implemented

LDRA tool suite
Include Page
LDRA_V
LDRA_V
96 S, 101 S, 107 S, 433 S, 458 SPartially Implemented

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

Bibliography

[Kettlewell 2002]Section 4.1, "time_t"

 

...

Image Added Image Added Image Added- Interesting time_t discussion from which I pulled my example code. Read it here