...
- 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 | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
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:
- Source and object code can significantly increase in size, perhaps by as much as 30 to 40 percent [Saks 2007b].
- All function return values must be checked . (See MEM32see ERR33-C. Detect and handle memory allocation standard library errors).)
- Functions should not return other values if they return error indicators . (See see ERR02-C. Avoid in-band error indicators).)
- Any function that allocates resources must ensure they are freed in cases where errors occur.
...
Code Block | ||||
---|---|---|---|---|
| ||||
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 isNULL
, 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 | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
#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 |
| 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 |
Probable |
High | P4 | L3 |
Automated Detection
Tool | Version | Checker | Description |
---|---|---|---|
Compass/ROSE |
Could detect violations of this rule merely by reporting functions that call | |||||||||
Parasoft C/C++test |
| CERT_C-ERR05-a | The 'abort()' function from the 'stdlib.h' or 'cstdlib' library shall not be used |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
SEI CERT C++ |
Coding Standard | VOID ERR05-CPP. Application-independent code should provide error detection without dictating error handling |
Bibliography
...
...