...
| Functions | Remediation |
|---|---|
rand(), srand() | MSC30-C. Do not use the rand() function for generating pseudorandom numbers |
getenv(), getenv_s() | ENV34-C. Do not store pointers returned by certain functions |
strtok() | strtok_s() in C11 Annex Kstrtok_r() in POSIX |
strerror() | strerror_s() in C11 Annex Kstrerror_r() in POSIX |
asctime(), ctime(),localtime(), gmtime()asctime_s(), ctime_s(), localtime_s(), gmtime_s() in C11 Annex K | strftime() |
setlocale() | Protect multithreaded access to locale-specific functions with a mutex |
ATOMIC_VAR_INIT, atomic_init() | Do not attempt to initialize an atomic variable from multiple threads |
tmpnam() | tmpnam_s() in C11 Annex Ktmpnam_r() in POSIX |
mbrtoc16(), c16rtomb(),mbrtoc32(), c32rtomb() | Do not call with a null mbstate_t * argument |
...
In this noncompliant code example, the function f() is called from within a multithreaded application but encounters an error while calling a system function. The strerror() function returns a human-readable error string given an error number.
The C Standard, 7.2426.6.2 3 paragraph 3 [ISO/IEC 9899:20112024], specifically states that strerror() is not required to avoid data races.
The strerror function is not required to avoid data races with other calls to the strerror function.
An implementation could write the error string into a static array and return a pointer to it, and that array might be accessible and modifiable by other threads.
...
This code first sets errno to 0 to comply 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 failure.
Compliant Solution (Annex K, strerror_s())
This compliant solution uses the strerror_s() function from Annex K of the C Standard, which has the same functionality as strerror() but guarantees thread-safety:
| Code Block | ||||
|---|---|---|---|---|
| ||||
#define __STDC_WANT_LIB_EXT1__ 1
#include <errno.h>
#include <stdio.h>
#include <string.h>
enum { BUFFERSIZE = 64 };
void f(FILE *fp) {
fpos_t pos;
errno = 0;
if (0 != fgetpos(fp, &pos)) {
char errmsg[BUFFERSIZE];
if (strerror_s(errmsg, BUFFERSIZE, errno) != 0) {
/* Handle error */
}
printf("Could not get the file position: %s\n", errmsg);
}
} |
Because Annex K is optional, strerror_s() may not be available in all implementations.
Compliant Solution (Compliant Solution (POSIX, strerror_r())
This compliant solution uses the POSIX strerror_r() function, which has the same functionality as strerror() but guarantees thread safety:
...
Race conditions caused by multiple threads invoking the same library function can lead to abnormal termination of the application, data integrity violations, or a denial-of-service attack.
Rule | Severity | Likelihood | Detectable | RepairableRemediation Cost | Priority | Level |
|---|---|---|---|---|---|---|
CON33-C | Medium | Probable | No | HighNo | P4 | L3 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
...
Tool | Version | Checker | Description | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Astrée |
| Supported, but no explicit checker | ||||||||||||||
| CodeSonar |
| BADFUNC.RANDOM.RAND | Use of | |||||||||||||
| Compass/ROSE | A module written in Compass/ROSE can detect violations of this rule | |||||||||||||||
| Cppcheck Premium |
| premium-cert-con33-c | ||||||||||||||
| Helix QAC |
| C5037 C++5021 DF4976, DF4977 | ||||||||||||||
| Klocwork |
| CERT.CONC.LIB_FUNC_USE | ||||||||||||||
| LDRA tool suite |
| 44 S | Partially Implemented | |||||||||||||
| Parasoft C/C++test |
| CERT_C-CON33-a | Avoid using thread-unsafe functions | |||||||||||||
| PC-lint Plus |
| 586 | Fully supported SECURITY-25 | |||||||||||||
| Data CERT C: Rule CON33-C | Checks for data race through standard library function call | Multiple tasks make unprotected calls to thread-unsafe standard library function | PRQA QA-C++ | ||||||||||||
| Include Page | cplusplus:PRQA QA-C++_V | cplusplus:PRQA QA-C++_V | 5021 | (rule fully covered) |
Related Guidelines
Key here (explains table format and definitions)
...
| [IEEE Std 1003.1:2013] | Section 2.9.1, "Thread Safety" |
| [ISO/IEC 9899:20112024] | Subclause 7.2426.6.23, "The |
| [Open Group 1997b] | Section 10.12, "Thread-Safe POSIX.1 and C-Language Functions" |
...