When developing new code, declare functions that return errno with a return type of errno_t. Many existing functions that return errno are declared as returning a value of type int. It is semantically unclear by inspecting the function declaration or prototype if these functions return an error status or a value or, worse, some combination of the two. (See ERR02-C. Avoid in-band error indicators.)
C11 Annex K introduced the new type errno_t that is defined to be type int in errno.h and elsewhere. Many of the functions defined in C11 Annex K return values of this type [ISO/IEC 9899:2011]. The errno_t type should be used as the type of an object that may contain only values that might be found in errno. For example, a function that returns the value of errno should be declared as having the return type errno_t.
This recommendation depends on C11 Annex K being implemented and advocates using errno_t in new code where appropriate. The following code can be added to remove this dependency:
| Code Block | ||
|---|---|---|
| ||
#ifndef __STDC_LIB_EXT1__ typedef int errno_t; #endif |
Noncompliant Code Example
...
This noncompliant code example nevertheless complies with ERR30-C. Set errno to zero before calling a library function known to set errno, and check errno only after the function returns a value indicating failureTake care when reading errno.
Compliant Solution (POSIX)
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#define __STDC_WANT_LIB_EXT1__ 1 #include <errno.h> #include <stdio.h> #include <stdlib.h> enum { NO_FILE_POS_VALUES = 3 }; errno_t opener( FILE *file, size_t *width, size_t *height, size_t *data_offset ) { size_t file_w; size_t file_h; size_t file_o; fpos_t offset; if (NULL == file) { return EINVAL; } errno = 0; if (fgetpos(file, &offset) != 0 ) { return errno; } if (fscanf(file, "%zu %zu %zu", &file_w, &file_h, &file_o) != NO_FILE_POS_VALUES) { return EIO; } errno = 0; if (fsetpos(file, &offset) != 0 ) { return errno; } if (width != NULL) { *width = file_w; } if (height != NULL) { *height = file_h; } if (data_offset != NULL) { *data_offset = file_o; } return 0; } |
This compliant solution is categorized as a POSIX solution because it returns EINVAL and , which are defined by POSIX (IEEE Std 1003.1, 2013 Edition) but not by the C Standard.EIO
...
Failing to test for error conditions can lead to vulnerabilities of varying severity. Declaring functions that return an errno with a return type of errno_t will not eliminate this problem but may reduce errors caused by programmers' misunderstanding the purpose of a return value.
Recommendation | Severity | Likelihood | Detectable |
|---|
Repairable | Priority | Level |
|---|---|---|
DCL09-C | Low |
Unlikely |
No |
Yes |
P2 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Axivion Bauhaus Suite |
| CertC-DCL09 | |||||||
| LDRA tool suite |
| 634 S | Partially Implemented |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
| SEI CERT C++ |
| Coding Standard | VOID DCL09-CPP. Declare functions that return errno with a return type of errno_t |
| ISO/IEC |
| TR 24772:2013 | Ignored Error Status and Unhandled Exceptions [OYB] |
Bibliography
...
Bibliography
...