| As noted in [undefined behavior 169|CC. Undefined Behavior#ub_169] of Annex J of \[[ISO/IEC 9899-1999|AA. Bibliography#ISO/IEC 9899-1999]\], the behavior a program is [undefined |BB. Definitions#undefined behavior] when | 
the pointer argument to the
freeorreallocfunction does not match a pointer earlier returned bycalloc,malloc, orrealloc, or the space has been deallocated by a call tofreeorrealloc.
Freeing memory multiple times has similar consequences to accessing memory after it is freed. (See rule MEM30-C. Do not access freed memory.) First, reading a pointer to deallocated memory is undefined because the pointer value is indeterminate and can have a trap representation . In the latter case, doing so can cause a hardware trap. When reading a freed pointer doesn't cause a trap, 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. One example of this is VU#623332, which describes a double-free vulnerability in the MIT Kerberos 5 function krb5_recvauth().
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. (See recommendation MEM04-C. Do not perform zero length allocations.)
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.
| 
int f(size_t n) {
  int error_condition = 0;
  int *x = (int*)malloc(n * sizeof(int));
  if (x == NULL)
    return -1;
  /* Use x and set error_condition on error. */
  if (error_condition == 1) {
    /* Handle error condition*/
    free(x);
  }
  /* ... */
  free(x);
  return error_condition;
}
 | 
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 set.
| 
int f(size_t n) {
  int error_condition = 0;
  if (n > SIZE_MAX / sizeof(int)) {
    errno = EOVERFLOW;
    return -1;
  }
  int *x = (int*)malloc(n * sizeof(int));
  if (x == NULL) {
    /* Report allocation failure to caller. */
    return -1;
  }
  /* Use x and set error_condition on error. */
  if (error_condition != 0) {
    /* Handle error condition and proceed. */
  }
  free(x);
  return error_condition;
}
 | 
Note that this solution checks for numeric overflow. (See rule INT32-C. Ensure that operations on signed integers do not result in overflow.)
Freeing memory multiple times can result in an attacker executing arbitrary code with the permissions of the vulnerable process.
| Rule | Severity | Likelihood | Remediation Cost | Priority | Level | 
|---|---|---|---|---|---|
| MEM31-C | high | probable | medium | P12 | L1 | 
| Tool | Version | Checker | Description | |||
|---|---|---|---|---|---|---|
| 
 | 
 | |||||
| 
 | 
 | 
 | 
 | |||
| 
 | 
 | 
 | ||||
| 
 | 
 | |||||
| 
 | 
 | |||||
| 
 | 
 | 
 | 
 | |||
|  | 
 | 
 | 
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
CERT C++ Secure Coding Standard: MEM31-CPP. Free dynamically allocated memory exactly once
ISO/IEC TR 24772 "XYK Dangling Reference to Heap" and "XYL Memory Leak"
MITRE CWE: CWE-415, "Double Free"
| \[[MIT 2005|AA. Bibliography#MIT 05]\] \[[OWASP, Double Free|AA. Bibliography#OWASP Double Free]\] \[[Viega 2005|AA. Bibliography#Viega 05]\] "Doubly freeing memory" \[[VU#623332|AA. Bibliography#VU623332]\] | 
      08. Memory Management (MEM)      MEM32-C. Detect and handle memory allocation errors