Versions Compared

Key

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

Wiki Markup
C99 defines {{assert()}} to have the following behavior \[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\]

The assert macro puts diagnostic tests into programs; it expands to a void expression. When it is executed, if expression (which shall have a scalar type) is false (that is, compares equal to 0), the assert macro writes information about the particular call that failed (including the text of the argument, the name of the source file, the source line number, and the name of the enclosing function — the latter are respectively the values of the preprocessing macros __FILE__ and __LINE__ and of the identifier __func__) on the standard error stream in an implementation-defined format. It then calls the abort function.

Since assert() calls abort(), any cleanup functions registered with atexit() will not be called. If the intention of the programmer is properly cleanup in the case of a failed assertion, a signal handler that calls exit() should be installed to handle SIGABRT.

Wiki Markup
See \[[ERR04-A. Choose an appropriate termination strategy]\] for more on {{abort()}} and terminating out of programs, and \[[MSC11-A. Incorporate diagnostic tests using assertions]\] for more on the {{assert()}} macro.

Non-Compliant Code Example

Code Block
bgColor#ffcccc
void cleanup(void) {
  /* delete temporary files, restore consistent state, etc */
}

int main(void) {
  atexit(cleanup);

  /* ... */

  assert(/* something bad didn't happen */);

  /* ... */
}

If the assert() fails, cleanup() will not be called.

Compliant Solution

Code Block
bgColor#ccccff
void sigabrt_handler(int signum) {
  exit(EXIT_FAILURE);
}

void cleanup(void) {
  /* delete temporary files, restore consistent state, etc */
}

int main(void) {
  atexit(cleanup);
  signal(SIGABRT, sigabrt_handler);

  /* ... */

  assert(/* something bad didn't happen */);

  /* ... */
}

Wiki Markup
Please note that this example is not a violation of \[[SIG30-C. Call only asynchronous-safe functions within signal handlers]\] since {{abort()}} is called synchronously by {{assert()}}.

Risk Analysis

Unsafe usage of abort() may leave files written in an inconsistent state. It may also leave sensitive temporary files on the filesystem.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

Related Vulnerabilities

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

References

Wiki Markup
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.2.1.1, "The {{assert}} macro", 7.20.4.1, "The {{abort}} function"


ERR05-A. Application-independent code must provide error detection without dictating error handling      12. Error Handling (ERR)       ERR30-C. Set errno to zero before calling a function, and use it only after the function returns a value indicating failure