Versions Compared

Key

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

...

Library Functions that Set errno and Return an Out-of-Band Error Indicator

The C Standard specifies that the functions listed in the following table set errno and return an out-of-band error indicator. That is, their return value on error can never be returned by a successful call.

A program may set and check errno for after invoking these library functions but is not required to do so. The program should not check the value of errno without first verifying that the function returned an error indicator. For example, errno should not be checked after calling signal() without first ensuring that signal() actually returned SIG_ERR.

...

Function Name

Return Value

errno Value

ftell()-1L Positive 

fgetpos(), fsetpos()

Nonzero

Positive

mbrtowc(), mbsrtowcs()

(size_t)(-1)

EILSEQ

signal()

SIG_ERR

Positive

wcrtomb(), wcsrtombs()

(size_t)(-1)

EILSEQ

mbrtoc16(), mbrtoc32()(size_t)(-1) EILSEQ
c16rtomb(), c32rtomb()(size_t)(-1) EILSEQ 

Library Functions that Set errno and Return an In-Band Error Indicator

The C Standard specifies that the functions listed in the following table set errno and return an in-band error indicator. That is, the return value when an error occurs is also a valid return value for successful calls. For example, the strtoul() function returns ULONG_MAX and sets errno to ERANGE if an error occurs. Because ULONG_MAX is a valid return value, errno must be used to check whether the only way to confirm that an error actually occurred. A program that uses errno for error checking must set it to 0 before calling one of these library functions and then inspect errno before a subsequent library function calloccurred when LONG_MAX is returned is to check errno.

The fgetwc() and fputwc() functions return WEOF in multiple cases, only one of which results in setting errno. The string conversion functions will return the maximum or minimum representable value and set errno to ERANGE if the converted value cannot be represented by the data type. However, if the conversion cannot happen because the input is invalid, the function will return 0, and the output pointer parameter will be assigned the value of the input pointer parameter, provided the output parameter is non-null.

...

A program that uses errno for error checking  a function that returns an in-band error indicator must set errno to 0 before calling one of these library functions and then inspect errno before a subsequent library function call.

Functions that Set errno Set errno and Return an In-Band Error Indicator

Function Name

Return Value

errno Value

fgetwc(), fputwc()

WEOF

EILSEQ

strtol(), wcstol()

LONG_MIN or LONG_MAX

ERANGE

strtoll(), wcstoll()

LLONG_MIN or LLONG_MAX

ERANGE

strtoul(), wcstoul()

ULONG_MAX

ERANGE

strtoull(), wcstoull()

ULLONG_MAX

ERANGE

strtoumax(), wcstoumax()

UINTMAX_MAX

ERANGE

strtod(), wcstod()

0 or ±HUGE_VAL

ERANGE

strtof(), wcstof()

0 or ±HUGE_VALF

ERANGE

strtold(), wcstold()

0 or ±HUGE_VALL

ERANGE

strtoimax(), wcstoimax()

INTMAX_MIN, INTMAX_MAX

ERANGE

Library Functions that Do Not Promise to Set errno

The C Standard fails to document the behavior of errno for some functions. For example, the setlocale() function normally returns a null pointer in the event of an error, but no guarantees are made about setting errno.

After calling one of these functions, a program should not rely solely on the value of errno to determine if an error occurred. The function might have altered errno, but this does not ensure that errno will properly indicate an error condition.

Library Functions with Differing Standards Documentation

If the program does check errno after calling one of these functions, it should set errno to 0 before the function call.

Library Functions with Differing Standards Documentation

Some functions behave differently regarding errno Some functions behave differently regarding errno in various standards. The fopen() function is one such example. When fopen() encounters an error, it returns a null pointer. The C Standard makes no mention of errno when describing fopen(). However, POSIX.1 declares that when fopen() encounters an error, it returns a null pointer and sets errno to a value indicating the error [IEEE Std 1003.1-2013]. The implication is that a program conforming to C but not to POSIX (such as a Windows program) should not check errno after calling fopen(), but a POSIX program may check errno if fopen() returns a null pointer.

Library Functions and errno

The following uses of errno are documented in the C Standard:

...

The POSIX.1 standard defines the use of errno by many more functions (including the C standard library function). POSIX also has a small set of functions that are exceptions to the rule. These functions have no return value reserved to indicate an error, but they still set errno on error. To detect an error, an application must set errno to 0 before calling the function and check whether it is nonzero after the call. Affected functions include strcoll(), strxfrm(), strerror(), wcscoll(), wcsxfrm(), and fwide(). The C Standard allows these functions to set errno to a nonzero value on success. Consequently, this type of error checking should be performed only on POSIX systems.

Noncompliant Code Example (strtoul())

This noncompliant code example fails to set errno to 0 before invoking strtoul(). If an error occurs, strtoul() returns a valid value (ULONG_MAX), so errno is the only means of determining if strtoul() ran successfully.

...

Any error detected in this manner may have occurred earlier in the program or may not represent an actual error.

Compliant Solution (strtoul())

This compliant solution sets errno to 0 before the call to strtoul() and inspects errno after the call:

Code Block
bgColor#ccccff
langc
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
 
void func(const char *c_str) {
  unsigned long number;
  char *endptr;
 
  errno = 0;
  number = strtoul(c_str, &endptr, 0);
  if (endptr == c_str || (number == ULONG_MAX 
                         && errno == ERANGE)) {
    /* Handle error */
  } else {
    /* Computation succeeded */
  }
}

Noncompliant Code Example (

...

ftell())

This noncompliant code example may fail to diagnose errors because fopen() might not set errno even if an error occurs:, after calling ftell(), examines errno without first checking whether the out-of-band indicator returned by ftell() indicates an error.

Code Block
bgColor#FFcccc
langc
#include <errno.h>
#include <stdio.h>
 
void func(const char *filenameFILE* fp) {
  FILE *fileptr;

  errno = 0;
  fileptr = fopen(filename, "rb"ftell(fp);
  if (errno != 0) {
    /* Handle error */perror("ftell");
  }
}

Compliant Solution (

...

ftell()

...

)

This compliant solution first detects that ftell() failed using its out-of-band error indicator. Once an error has been confirmed, reading errno (implicitly by using the perror() function) is permitted.The C Standard makes no mention of errno when describing fopen(). In this compliant solution, the results of the call to fopen() are used to determine failure and errno is not checked:

Code Block
bgColor#ccccff
langc
#include <errno.h>
#include <stdio.h>
 
void func(const char *filenameFILE* fp) {
  FILE *fileptr = fopen(filename, "rb");
  if (ftell(fileptrfp) == NULL-1)  {
    /* An error occurred in fopen() */perror("ftell");
  }
}

...

Noncompliant Code Example (fopen()

...

)

This noncompliant code example may fail to diagnose errors because fopen() might not set errno even if an error occurs:

In this compliant solution, errno is checked only after an error has already been detected by another means:

Code Block
bgColor#ccccff#FFcccc
langc
#include <errno.h>
#include <stdio.h>
 
void func(const char *filename) {
  FILE *fileptr;

  errno = 0;
  fileptr = fopen(filename, "rb");
  if (fileptrerrno !== NULL0)  {
    /*
 Handle   error */
 An error occurred in fopen(); now it's valid 
     * to examine errno. }
}

Compliant Solution (fopen(), C)

The C Standard makes no mention of errno when describing fopen(). In this compliant solution, the results of the call to fopen() are used to determine failure and errno is not checked:

Code Block
bgColor#ccccff
langc
#include <stdio.h>
 
void func(const char *filename) {
  FILE *fileptr = fopen(filename, "rb");
  if (fileptr == NULL)  {
     /*/
 An error occurred in perrorfopen(filename); */
  }
}

Risk Assessment

The improper use of errno may result in failing to detect an error condition or in incorrectly identifying an error condition when none exists.

...

Rule

...

Severity

...

Likelihood

...

Remediation Cost

...

Priority

...

Level

...

ERR30-C

...

Medium

...

Probable

...

Medium

...

P8

...

L2

Compliant Solution (fopen(), POSIX)

In this compliant solution, errno is checked only after an error has already been detected by another means:

Code Block
bgColor#ccccff
langc
#include <errno.h>
#include <stdio.h>
 
void func(const char *filename) {
  FILE *fileptr;

  errno = 0;
  fileptr = fopen(filename, "rb");
  if (fileptr == NULL)  {
    /*
     * An error occurred in fopen(); now it's valid 
     * to examine errno.
     */
    perror(filename);
  }
}

Risk Assessment

The improper use of errno may result in failing to detect an error condition or in incorrectly identifying an error condition when none exists.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

ERR30-C

Medium

Probable

Medium

P8

L2

Automated Detection

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_V
Astrée_V
errno-resetPartially checked
Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-ERR30Fully implemented
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

LANG.STRUCT.RC

Redundant Condition

Compass/ROSE

Could detect violations of this rule by ensuring that each library function is accompanied by the proper treatment of errno

Coverity
Include Page
Coverity_V
Coverity_V

MISRA C 2012 Rule 22.8

MISRA C 2012 Rule 22.9

MISRA C 2012 Rule 22.10

Implemented
Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C2500, C2501, C2502, C2503 

C++3172, C++3173, C++3174, C++3175, C++3176, C++3177, C++3178, C++3179, C++3183, C++3184


Klocwork
Include Page
Klocwork_V
Klocwork_V

CXX.ERRNO.NOT_SET
CXX.ERRNO.NOT_CHECKED
CXX.ERRNO.INCORRECTLY_CHECKED


Automated Detection

2500, 2501, 2502, 2503 

Tool

Version

Checker

Description

Astrée
Include Page
Astrée_VAstrée_Verrno-resetPartially checkedAxivion Bauhaus Suite
Include Page
Axivion Bauhaus Suite_VAxivion Bauhaus Suite_VCertC-ERR30Fully implementedCompass/ROSE

Could detect violations of this rule by ensuring that each library function is accompanied by the proper treatment of errno

Coverity
Include Page
Coverity_VCoverity_V

MISRA C 2012 Rule 22.8

MISRA C 2012 Rule 22.9

MISRA C 2012 Rule 22.10

ImplementedLDRA tool suite
Include Page
LDRA_V
LDRA_V

111 D, 121 D, 122 D, 132  D, 134 D

Fully implemented
Parasoft C/C++test
Include Page
Parasoft_VParasoft_V

CERT_C-ERR30-a
CERT_C-ERR30-b

Properly use errno value
Provide error handling for file opening errors right next to the call to fopen

C++test
Include Page
Parasoft_V
Parasoft_V

CERT_C-ERR30-a
CERT_C-ERR30-b

Properly use errno value
Provide error handling for file opening errors right next to the call to fopen

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rule ERR30-C


Checks for:

  • Misuse of errno
  • Errno not reset

Rule fully covered.

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_VPolyspace Bug Finder_V

Errno not reset

Misuse of errno

MISRA C:2012 Rule 22.8

MISRA C:2012 Rule 22.10

errno not reset before calling a function that sets errno

errno incorrectly checked for error conditions

The value of errno shall be set to zero prior to a call to an errno-setting-function

The value of errno shall only be tested when the last function to be called was an errno-setting function

 PRQA QA-C
Include Page
PRQA QA-C_vPRQA QA-C_v

Related Vulnerabilities

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

Related Guidelines

Key here (explains table format and definitions)

Taxonomy

Taxonomy item

Relationship

CERT C Secure Coding StandardEXP12-C. Do not ignore values returned by functionsPrior to 2018-01-12: CERT: Unspecified Relationship
ISO/IEC TS 17961:2013Incorrectly setting and using errno [inverrno]Prior to 2018-01-12: CERT: Unspecified Relationship
CWE 2.11CWE-456, Missing Initialization of a Variable2017-07-05: CERT: Rule subset of CWE

CERT-CWE Mapping Notes

Key here for mapping notes

CWE-456 and ERR30-C

CWE-456 = EXP33-C

CWE-456 = Union( ERR30-C, list) where list =

...

  • Reading potentially uninitialized variables besides errno


CWE-248 and ERR30-C

Intersection( CWE-248, ERR30-C) = Ø

CWE-248 is only for languages that support exceptions. It lists C++ and Java, but not C.

Bibliography

[Brainbell.com]Macros and Miscellaneous Pitfalls
[Horton 1990]Section 11, p. 168
Section 14, p. 254
[IEEE Std 1003.1-2013]XSH, System Interfaces, fopen
[Koenig 1989]Section 5.4, p. 73
[Summit 2005]

...