...
- rand()
- getenv()
- strtok()
- strerror()
- asctime()
- ctime()
Non Compliant Code
Consider a multithreaded application which involves a function which returns a random value each time it is invoked. According to POSIX implementation, rand() returns the next pseudorandom number in the sequence determined by an initial seed value. The rand() function updates the seed value, which is stored at a library allocated static memory location. If two threads concurrently invoke the rand() function, it may result in undefined behavior and may also result in rand() returning the same value in both the threads.
Code Block | ||
---|---|---|
| ||
int get_secret() { int secret = (rand() % 100) + 100; return secret; } |
Compliant Solution
The compliant solution uses a mutex to make each call to rand() function atomic.
Code Block | ||
---|---|---|
| ||
#include <threads.h> mtx_t rand_lock; int get_secret() { int secret; mtx_lock(&rand_lock) ; secret = (rand() % 100) + 100; mtx_unlock(&rand_lock); return secret; } void init(){ /* initialize a simple non-recursive mutex */ if(mtx_init(&rand_lock, mtx_plain) == thrd_error){ abort(); } /* other initialization code */ } |
Risk Assessment
Race conditions caused by multiple threads invoking the same library function can lead to abnormal termination of the application, data integrity violations or denial of service attack.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
C1X00-C | medium | probable | High | P4 | L3 |
Automated Detection
A module can be written in Compass/ROSE to detect violations of this rule.
References
Wiki Markup |
---|
\[[N1401-C1X Draft|http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1401.pdf]\] Section 7.21.2.1 rand() function, Section 7.21.4.6 getenv() function, Section 7.22.5.8 strtok() function, Section 7.22.6.2 strerror() function, Section 7.25.3.1 asctime() function, Section 7.25.3.2 ctime() function \[[POSIX.1 Thread Safety|http://www.unix.org/whitepapers/reentrant.html]\] |
...