Some functions in the C standard library are not guaranteed to be reentrant with respect to threads. Some functions (such as strtok()
and asctime()
) return a pointer to the result stored in function-allocated memory on a per-process basis. Other functions (such as rand()
) store state information in function-allocated memory on a per-process basis. Multiple threads invoking the same function can cause concurrency problems, which often result in abnormal behavior and can cause more serious vulnerabilities, such as abnormal termination, denial-of-service attack, and data integrity violations.
As per the N1401-C1X documentAccording to the C Standard [ISO/IEC 9899:2011], the following library functions are not required to avoid data races:
...
Section 2.9.1 of the System Interfaces volume of POSIX.1-2008 has a much longer list of functions that are not required to be thread-safe.
Noncompliant Code Example
Consider a multithreaded application that encounters an error while calling a system function. The strerror()
function returns a human-readable error string given an error number. C99The C Standard, Section section 7.2224.6.2, specifically states that strerror()
is not required to avoid data races. Conventionally, it could rely on a static array that maps error numbers to error strings, and that array might be accessible and modifiable by other threads.
...
Note that this code first sets errno
to 0 to comply with rule 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.
...
Note that Linux provides two versions of strerror_r()
, known as the XSI-compliant version and the GNU-specific version. This compliant solution assumes the XSI-compliant version. You can get the XSI-compliant version if you compile applications in the way POSIX requires (that is, by defining _POSIX_C_SOURCE
or _XOPEN_SOURCE
appropriately). Check your strerror_r()
manual page to see which version(s) are available on your system.
Compliant Solution (strerror_s
)
The 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 | ||||
---|---|---|---|---|
| ||||
errno = 0; FILE* fd = fopen( filename, "r"); if (fd == NULL) { char errmsg[BUFSIZ]; if (strerror_s(errno, errmsg, BUFSIZ) != 0) { /* handle error */ } printf("Could not open file because of %s\n", errmsg); } |
...
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
CON33-C | medium | probable | high | P4 | L3 |
Related Guidelines
...
Automated Detection
Tool | Version | Checker | Description | section|
---|---|---|---|---|
Compass/ROSE |
|
| Section | A module written in Compass/ROSE can detect violations of this rule. |
Bibliography
Related Guidelines
CERT C++ Secure Coding Standard: CON03-CPP. Avoid assuming functions are thread safe unless otherwise specified.
ISO/IEC 9899:2011 [N1401-C1X Draft] Section 7.2122.2.1, "The rand
() function," Section 7.2122.4.6, "The getenv
() function," Section 7.2224.5.8, "The strtok
() function," Section 7.2224.6.2, "The strerror
() function," Section 7.2527.3.1, "The asctime
() function," Section 7.2527.3.2, "The ctime
() function"
Sources
[Historical information about POSIX.1 Thread Safety]
...