Freeing memory multiple times has similar consequences to accessing memory after it is freed. The underlying data structures that manage the heap can become corrupted in a way that can introduce security vulnerabilities into a program. These types of issues are referred to as double-free vulnerabilities. In practice, double-free vulnerabilities can be exploited to execute arbitrary code.
To eliminate double-free vulnerabilities, it is necessary to guarantee that dynamic memory is freed exactly one time. Programmers should be wary when freeing memory in a loop or conditional statement; if coded incorrectly, these constructs can lead to double-free vulnerabilities. It is also a common error to misuse the realloc() function in a manner that results in double-free vulnerabilities
In this noncompliant code example, the memory referred to by x may be freed twice: once if error_condition is true and again at the end of the code.
Code:
size_t num_elem = /* some initial value */;
int error_condition = 0;
int *x = (int *)malloc(num_elem * sizeof(int));
if (x == NULL) {
/* handle allocation error */
}
/* ... */
if (error_condition == 1) {
/* handle error condition*/
free(x);
x = NULL;
}
/* ... */
free(x);
x = NULL;
In this compliant solution, the free a referenced by x is only freed once. This is accomplished by eliminating the call to free() when error_condition is equal to 1.
Code:
size_t num_elem = /* some initial value */;
int error_condition = 0;
if (num_elem > SIZE_MAX/sizeof(int)) {
/* Handle overflow */
}
int *x = (int *)malloc(num_elem * sizeof(int));
if (x == NULL) {
/* handle allocation error */
}
/* ... */
if (error_condition == 1) {
/* Handle error condition*/
}
/* ... */
free(x);
x = NULL;
Note that this solution checks for numeric overflow.
Cheers