Use ferror()
to check for any accumulated errors, for example, after a long string of stdio calls.
Non-Compliant Coding Example
Many implementations of the stdio package adjust their behavior slightly if stdout
is a terminal. To make the determination, these implementations perform some operation which happens to fail (with ENOTTY
) if stdout is not a terminal. Although the output operation goes on to complete successfully, errno
still contains ENOTTY
. This behavior can be mildly confusing, but it is not strictly incorrect, because it is only meaningful for a program to inspect the contents of errno after an error has been reported. (More precisely, errno is only meaningful after a library function that sets errno
on error has returned an error code.)
errno = 0; printf("This\n"); printf("is\n"); printf("a\n"); printf("test.\n"); if (errno != 0) { fprintf(stderr, "printf failed: %s\n", strerror(errno)); }
Compliant Solution
This compliant solution uses ferror()
to detect an error. In addition, if an early printf()
fails, later ones may modify errno
, so the program cannot rely on being able to detect the root cause of the first failure if it waits until after a sequence of library calls to check.
printf("This\n"); printf("is\n"); printf("a\n"); printf("test.\n"); if (ferror(stdout)) { fprintf(stderr, "printf failed\n"); }
Risk Assessment
Checking errno
after multiple calls to library functions can lead to spurious error reporting, possibly resulting in incorrect program operation.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
ERR01-A |
3 (high) |
3 (likely) |
1 (high) |
P9 |
L2 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[[Horton 90]] Section 14 p. 254
[[ISO/IEC 9899-1999]] Section 6.3.1.1, "Boolean, characters, and integers", Section 7.1.4, Section 7.9.10.3
[[Koenig 89]] Section 5.4 p. 73
ERR00-A. Detect errors by checking return values 13. Error Handling (ERR) ERR02-A. Return an errno-style value to indicate an error