Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Parasoft 2020.2

...

  • A return value (especially of type errno_t)
  • An argument passed by address
  • A global object (e.g., such as errno)
  • longjmp()
  • Some combination of the above

...

Code Block
bgColor#ffcccc
langc
void g(void) {
  /* ... */
  if (something_really_bad_happens) {
    fprintf(stderr, "Something really bad happened!\n");
    abort();
  }
  /* ... */
}

void f(void) {
  g();
  /* ... doDo the rest of f ... */
}

If something_really_bad_happens in g(), the function prints an error message to stderr and then calls abort(). The problem is that this application-independent code does not know the context in which it is being called, so it is erroneous to handle the error.

...

Code Block
bgColor#ccccff
langc
const errno_t ESOMETHINGREALLYBAD = 1;

errno_t g(void) {
  /* ... */
  if (something_really_bad_happens) {
    return ESOMETHINGREALLYBAD;
  }
  /* ... */
  return 0;
}

errno_t f(void) {
  errno_t status = g();
  if (status != 0) {
    return status;
  }

  /* ... doDo the rest of f ... */

  return 0;
}

...

A return type of errno_t indicates that the function returns a status indicator . (See see DCL09-C. Declare functions that return errno with a return type of errno_t).)

This error-handling approach is secure, but it has the following drawbacks:

...

Code Block
bgColor#ccccff
langc
const errno_t ESOMETHINGREALLYBAD = 1;

void g(errno_t * err) {
  if (err == NULL) {
    /* Handle null pointer */
  }
  /* ... */
  if (something_really_bad_happens) {
    *err = ESOMETHINGREALLYBAD;
  } else {
    /* ... */
    *err = 0;
  }
}

void f(errno_t * err) {
  if (err == NULL) {
    /* Handle null pointer */
  }
  g(err);
  if (*err == 0) {
    /* ... doDo the rest of f ... */
  }
  return 0;
}

...

  • A return status can be returned only if the caller provides a valid pointer to an object of type errno_t. If this argument is NULL, there is no way to indicate this error.
  • Source code becomes even larger because of the possibilities of receiving a null pointer.
  • All error indicators must be checked after calling functions.
  • Any function that allocates resources must ensure they are freed in cases where errors occur.
  • Unlike return values, static analysis tools generally do not diagnose a failure to check error indicators passed as argument pointers.

...

Code Block
bgColor#ccccff
langc
errno_t my_errno; /* alsoAlso declared in a .h file */
const errno_t ESOMETHINGREALLYBAD = 1;

void g(void) {
  /* ... */
  if (something_really_bad_happens) {
    my_errno = ESOMETHINGREALLYBAD;
    return;
  }
  /* ... */
}

void f(void) {
  my_errno = 0;
  g();
  if (my_errno != 0) {
    return;
  }
  /* ... doDo the rest of f ... */
}

The call to f() provides a status indicator that is 0 upon success and a nonzero value upon failure.

...

Code Block
bgColor#ccccff
langc
#include <setjmp.h>

const errno_t ESOMETHINGREALLYBAD = 1;

jmp_buf exception_env;

void g(void) {
  /* ... */
  if (something_really_bad_happens) {
    longjmp(exception_env, ESOMETHINGREALLYBAD);
  }
  /* ... */
}

void f(void) {
  g();
  /* ... doDo the rest of f ... */
}

/* ... */
if (setjmp(exception_env) != 0) {
  /*
   * If we get here, an error occurred; 
   * do not continue processing.
   */
}
/* ... */
f();
/* If we get here, no errors occurred */
/* ... */

...

The following table summarizes the characteristics of error-reporting and error-detection mechanisms.

Method

Code Increase

Manages Allocated Resources

Automatically Enforceable

Return value

Big (30–40%)

No

Yes

Address argument

Bigger

No

No

Global indicator

Medium

No

Yes

longjmp()

Small

No

n/a

Risk Assessment

Lack of an error-detection mechanism prevents applications from knowing when an error has disrupted normal program behavior.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

ERR05-C

medium

Medium

probable

Probable

high

High

P4

L3

Automated Detection

Tool

Version

Checker

Description

Compass/ROSE

 

 



Could detect violations of this rule merely by reporting functions that call abort(), exit(), or _Exit() inside an if or switch statement.
This would also catch many false positives, as ROSE could not distinguish a library function from an application function

Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

CERT_C-ERR05-a
CERT_C-ERR05-b
CERT_C-ERR05-c

The 'abort()' function from the 'stdlib.h' or 'cstdlib' library shall not be used
The 'exit()' function from the 'stdlib.h' or 'cstdlib' library shall not be used
The 'quick_exit()' and '_Exit()' functions from the 'stdlib.h' or 'cstdlib' library shall not be u

Related Vulnerabilities

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

Related Guidelines

Bibliography

...


...

Image Modified Image Modified Image Modified