...
In this noncompliant example, the array elements a[n..2n]
are uninitialized when they are accessed in the for loop.:
Code Block | ||||
---|---|---|---|---|
| ||||
void g(double *a, size_t n) { a = (double *)realloc(a, (n * 2 + 1) * sizeof(double)); if (a != NULL) { for (size_t i = 0; i != n * 2 + 1; ++i) { if (a[i] < 0) { a[i] = -a[i]; /* violation */ } } /* ... */ free(a); } } |
...
In this compliant example, the array elements a[n..2n]
are initialized to 0
when they are accessed in the for loop.:
Code Block | ||||
---|---|---|---|---|
| ||||
void g(double *a, size_t n) { a = (double *)calloc(a, (n * 2 + 1) * sizeof(double)); if (a != NULL) { for (size_t i = 0; i != n * 2 + 1; ++i) { if (a[i] < 0) { a[i] = -a[i]; } } /* ... */ free(a); } } |
...
In this noncompliant code example, the report_error()
function has been modified so that error_log
is properly initialized.:
Code Block | ||||
---|---|---|---|---|
| ||||
void report_error(const char *msg) { const char *error_log = msg; char buffer[24]; sprintf(buffer, "Error: %s", error_log); printf("%s\n", buffer); } |
...
In this compliant solution, the magic number is abstracted, and the buffer overflow is eliminated.:
Code Block | ||||
---|---|---|---|---|
| ||||
enum {max_buffer = 24}; void report_error(const char *msg) { const char *error_log = msg; char buffer[max_buffer]; snprintf(buffer, sizeof(buffer), "Error: %s", error_log); printf("%s\n", buffer); } |
...
The previous noncompliant code example can be solved by using a more reliable source for random number generation. This compliant solution uses the CPU clock in addition to the real-time clock to seed the random number generator.:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <time.h> double cpu_time; struct timeval tv; unsigned long junk; cpu_time = ((double) clock()) / CLOCKS_PER_SEC; gettimeofday(&tv, NULL); srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec ^ junk); |
...
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Compass/ROSE | Automatically detects simple violations of this rule, although it may return some false positives. It may not catch more complex violations, such as initialization within functions taking uninitialized variables as arguments. It does catch the second noncompliant code example, and can be extended to catch the first as well. | ||||||||
Coverity | 6.5 | UNINIT | Fully Implementedimplemented | ||||||
5.0 | NO_EFFECT | Can find cases of an uninitialized variable being used before it is initialized, although it cannot detect cases of uninitialized members of a struct . Because Coverity Prevent cannot discover all violations of this rule, further verification is necessary. | |||||||
Fortify SCA | Can detect violations of this rule, but will return false positives if the initialization was done in another function. | ||||||||
GCC | 4.3.5 | Can detect some violations of this rule when the | |||||||
9.1 | UNINIT.HEAP.MIGHT | ||||||||
| 57 D | Fully implemented. | |||||||
PRQA QA-C |
| 2961 (D) 2962 (A) 2963 (S) 2971 (D) 2972 (A) | Fully implemented. | ||||||
Splint | 3.1.1 |
Related Vulnerabilities
CVE-2009-1888 results from a violation of this recommendation. Some versions of SAMBA (up to 3.3.5) call a function which takes in two potentially uninitialized variables involving access rights. An attacker can exploit this to bypass the access control list and gain access to protected files files [xorl 2009].
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
...