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.

...

One way to inform the calling function of errors is to return a value indicating success or failure. This compliant solution ensures each function returns a value of type errno_t, where 0 indicates that no error has occurred.:

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:

...

Instead of encoding status indicators in the return value, each function can take a pointer as an argument, which is used to indicate errors. In the following example, each function uses an errno_t\ * argument to report errors.:

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