Avoid in-band error indicators while designing interfaces. This practice is commonly used by C library functions but is not recommended. One example from the C standard of a troublesome in-band error indicator is EOF
. (see See rules FIO34-C. Use int to capture the return value of character IO functions and FIO35-C. Use feof() and ferror() to detect end-of-file and file errors when sizeof(int) == sizeof(char).) . Another problematic use of in-band error indicators from the C standard involving the size_t
and time_t
types is described by rule MSC31-C. Ensure that return values are compared against the proper type.
...
The sprintf()
function returns the number of characters written in the array, not counting the terminating null character. This number is frequently added to an existing counter to keep track of the location of the index into the array. However, the call to sprintf()
can (and will) return -1 on error conditions, such as an encoding error. If this happens on the first call (which is likely), the count
variable, already at zero, is decremented. If this index is subsequently used, it will result in an out-of-bounds read or write.
...
Wiki Markup |
---|
This compliant solution shows the redesigned API for {{sprintf()}} from the CERT managed string library \[[Burch 062006|AA. Bibliography#Burch06]\]. |
...
The ssize_t
data type is designed as a "signed representation of size_t
." . Consequently, it is often used as a return type for functions that can return an unsigned value upon success and a negative value upon error. For instance, the POSIX read()
function has the following signature:
Code Block | ||
---|---|---|
| ||
ssize_t read(int fildes, void *buf, size_t nbyte); |
It read()
returns -1 if an error occurs, or, if no errors occur, it returns the number of bytes actually read if no errors occur.
As with all in-band error indicators, this type is not recommended. This is because developers are tempted to ignore the possibility that a ssize_t value is negative.
...
An alternative hypothetical signature for the read()
function would be:
Code Block | ||
---|---|---|
| ||
errno_t read(int fildes, void *buf, size_t nbyte, size_t* rbytes); |
...
ERR02-EX1: Null pointers are another example of an in-band error indicator. Use of null pointers is allowed because it is supported by the language. According to C99, Section 6.3.2.3:
If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
...
For example, the functions defined in TR24731-1 provide hooks for internal constraint violations. If a constraint violation handler is guaranteed not to return upon an error occurring, then you may safely ignore errors returned by these functions. You might accomplish this by having the constraint-violation handler call abort()
, or longjmp()
, for instance.
See recommendation ERR03-C. Use runtime-constraint handlers when calling functions defined by TR24731-1 for more on the functions defined in TR24731-1.
...
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
Related Guidelines
CERT This rule appears in the C++ Secure Coding Standard as : ERR02-CPP. Avoid in-band error indicators.
The CERT Oracle This rule appears in the Java Secure Coding Standard as for Java: MET09-J. Always provide feedback about the resulting value of a method.
Bibliography
\[[Burch 06|AA. Bibliography#Burch06]\]
\[[ISO/IEC 9899:1999|AA. Bibliography#ISO/IEC 9899-1999]\] Section 6.2.4, "Storage durations of objects," and Section 7.20.3, "Memory management functions"
\[[ Wiki Markup
ISO/IEC PDTR 24772|AA. Bibliography#ISO/IEC PDTR 24772]\] "NZN Returning error status" \[[
Bibliography
Wiki Markup |
---|
\[[Burch 2006|AA. Bibliography#ISO/IEC TR 24731-1-2007Bibliography#Burch06]\] |
...
12. Error Handling (ERR) ERR03-C. Use runtime-constraint handlers when calling functions defined by TR24731-1