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.
According to the C C11 Standard, the following library functions are not required to avoid data races:
API | Recommendation |
---|---|
rand() , srand() | MSC30-C. Do not use the rand() function for generating pseudorandom numbers |
getenv() , getenv_s() | |
strtok() | strtok_s() in C11 Annex K, or strtok_r() in POSIX |
strerror() | strerror_s() in C11 Annex K, or strerror_r() in POSIX |
asctime() , ctime() ,localtime() , gmtime() | asctime_s() , ctime_s() , localtime_s() , gmtime_s() in C11 Annex K |
setlocale() | |
ATOMIC_VAR_INIT , atomic_init() | |
tmpnam() |
...
tmpnam_s() in C11 Annex K, tmpnam_r() in POSIX | |
mbrtoc16() , c16rtomb() ,mbrtoc32() , c32rtomb() |
...
Do not call with a |
...
null mbstate_t * argument |
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.
...
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. Furthermore, in CC11, errno
is a thread-local variable, so there is no race condition between the time it is initialized and the time it is read by strerror_s()
.
...