As noted in undefined behavior 179 of Annex J of the C standard [ISO/IEC 9899:2011], the behavior of a program is undefined when
the pointer argument to the
free
orrealloc
function does not match a pointer earlier returned by a memory management function, or the space has been deallocated by a call tofree
orrealloc
.
Freeing memory that is not allocated dynamically can lead to serious errors similar to those discussed in MEM31-C. Free dynamically allocated memory exactly once. The specific consequences of this error depend on the implementation, but they range from nothing to abnormal program termination. Regardless of the implementation, avoid calling free()
on anything other than a pointer returned by a dynamic-memory allocation function, such as malloc()
, calloc()
, realloc()
, or aligned_alloc
.
...
Code Block | ||||
---|---|---|---|---|
| ||||
enum { MAX_ALLOCATION = 1000 }; int main(int argc, const char *argv[]) { char *str = NULL; size_t len; if (argc == 2) { len = strlen(argv[1])+1; if (len > MAX_ALLOCATION) { /* Handle error */ } str = (char *)malloc(len); if (str == NULL) { /* Handle allocation error */ } strcpy(str, argv[1]); } else { printf("%s\n", "usage: $>a.exe [string]"); return -1; } /* ... */ free(str); return 0; } |
Noncompliant Code Example (realloc()
)
In this noncompliant example, the pointer parameter to realloc()
, buf
, does not refer to dynamically allocated memory.
Code Block | ||||
---|---|---|---|---|
| ||||
#define BUFSIZE 256
void f(void) {
char buf[BUFSIZE];
char *p;
/* ... */
p = (char *)realloc(buf, 2 * BUFSIZE); /* violation */
/* ... */
}
|
Compliant Solution(realloc()
)
In this compliant solution, buf
refers to dynamically allocated memory.
Code Block | ||||
---|---|---|---|---|
| ||||
#define BUFSIZE 256
void f(void) {
char *buf = (char *)malloc(BUFSIZE * sizeof(char));
char *p;
/* ... */
p = (char *)realloc(buf, 2 * BUFSIZE); /* violation */
/* ... */
} |
Risk Assessment
Freeing or reallocating memory that was not dynamically allocated can lead to arbitrary code execution if that memory is reused by malloc()
.
...
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
| 483 S | Fully implemented. | |||||||
| BAD_FREE | Identifies calls to | |||||||
| FNH.MIGHT | ||||||||
Compass/ROSE | Can detect some violations of this rule. |
...
MITRE CWE: CWE-590, "Free of invalid pointer not on the heap"
Bibliography
[Seacord 2005] Chapter 4, "Dynamic Memory Management"
...