Main Content

CWE Rule 391

Unchecked Error Condition

Since R2024a

Description

Rule Description

[PLANNED FOR DEPRECATION. SEE MAINTENANCE NOTES AND CONSIDER CWE-252, CWE-248, OR CWE-1069.] Ignoring exceptions and other error conditions may allow an attacker to induce unexpected behavior unnoticed.

Polyspace Implementation

The rule checker checks for Errno not checked.

Examples

expand all

Issue

This issue occurs when you call a function that sets errno to indicate error conditions, but do not check errno after the call. For these functions, checking errno is the only reliable way to determine if an error occurred.

Functions that set errno on errors include:

  • fgetwc, strtol, and wcstol.

    For a comprehensive list of functions, see documentation about errno.

  • POSIX® errno-setting functions such as encrypt and setkey.

Risk

To see if the function call completed without errors, check errno for error values.

The return values of these errno-setting functions do not indicate errors. The return value can be one of the following:

  • void

  • Even if an error occurs, the return value can be the same as the value from a successful call. Such return values are called in-band error indicators.

You can determine if an error occurred only by checking errno.

For instance, strtol converts a string to a long integer and returns the integer. If the result of conversion overflows, the function returns LONG_MAX and sets errno to ERANGE. However, the function can also return LONG_MAX from a successful conversion. Only by checking errno can you distinguish between an error and a successful conversion.

Fix

Before calling the function, set errno to zero.

After the function call, to see if an error occurred, compare errno to zero. Alternatively, compare errno to known error indicator values. For instance, strtol sets errno to ERANGE to indicate errors.

The error message in the Polyspace® result shows the error indicator value that you can compare to.

Example — errno Not Checked After Call to strtol
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>

int main(int argc, char *argv[]) {
    char *str, *endptr;
    int base;
    
    str = argv[1];
    base = 10;
    
    long val = strtol(str, &endptr, base); //Noncompliant
    printf("Return value of strtol() = %ld\n", val);
}

You are using the return value of strtol without checking errno.

Correction — Check errno After Call

Before calling strtol, set errno to zero. After a call to strtol, check the return value for LONG_MIN or LONG_MAX and errno for ERANGE.

#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<limits.h>

int main(int argc, char *argv[]) {
    char *str, *endptr;
    int base;
    
    str = argv[1];
    base = 10;
    
    errno = 0;
    long val = strtol(str, &endptr, base);
    if((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE) {
         printf("strtol error");
         exit(EXIT_FAILURE);
    }        
    printf("Return value of strtol() = %ld\n", val);
}

Check Information

Category: Error Conditions, Return Values, Status Codes

Version History

Introduced in R2024a