According \[ [ISO/IEC 9899-1999|AA. Bibliography#ISO/IEC 9899-1999]\], the behavior of a program that uses the value of a pointer that refers to space deallocated by a call to the {{ Wiki Markup free()
}} or {{realloc()
}} function is [undefined |BB. Definitions#undefined behavior]. (See [undefined behavior 168 |CC. Undefined Behavior#ub_ 168 ] of Annex J.)
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 may cause a hardware trap.
...
Noncompliant Code Example
...
This example from Kernighan and Ritchie \[ [Kernighan 1988|AA. Bibliography#Kernighan 88]\] shows both the incorrect and correct techniques for deleting items from a linked list. The incorrect solution, clearly marked as wrong in the book, is bad because {{p
}} is freed before the {{p->next
}} is executed, so {{p->next
}} reads memory that has already been freed.
Code Block | ||||
---|---|---|---|---|
| ||||
for (p = head; p != NULL; p = p->next) free(p); |
...
Noncompliant Code Example
...
In this noncompliant example ([CVE-2009-1364|http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2009-1364]) from {{libwmf
}} version 0.2.8.4, the return value of {{gdRealloc
}} (a simple wrapper around {{realloc
}} which reallocates space pointed to by {{im->clip->list
}}) is set to {{more
}}. However, the value of {{im->clip->list
}} is used directly afterwards in the code, and [ISO/IEC 9899:1999|AA. Bibliography#ISO/IEC 9899-1999] specifies that if {{realloc
}} moves the area pointed to, then the original is freed. An attacker can then execute arbitrary code by forcing a reallocation (with a sufficient {{im->clip->count
}}) and accessing freed memory \[ [xorl 2009|http://xorl .wordpress.com/2009/05/05/cve- 2009-1364-libwmf-pointer-use-after-free/]\].
Code Block | ||||
---|---|---|---|---|
| ||||
void gdClipSetAdd(gdImagePtr im,gdClipRectanglePtr rect) { gdClipRectanglePtr more; if (im->clip == 0) { ... } if (im->clip->count == im->clip->max) { more = gdRealloc (im->clip->list,(im->clip->max + 8) * sizeof (gdClipRectangle)); if (more == 0) return; //if the realloc fails, then we have not lost the im->clip->list value im->clip->max += 8; } im->clip->list[im->clip->count] = (*rect); im->clip->count++; |
...
Tool | Version | Checker | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
|
| ||||||||||||
|
|
|
| ||||||||||||
|
|
|
| ||||||||||||
|
|
|
| ||||||||||||
|
|
|
| ||||||||||||
|
|
|
|
...
MITRE CWE: CWE-416, "Use After Free"
Bibliography
\[[Kernighan 1988|AA. Bibliography#Kernighan 88]\] Section 7.8.5, "Storage Management"
\[ Wiki Markup
[OWASP Freed Memory|AA. Bibliography#OWASP Freed Memory]\]
\[
[Seacord 2005a|AA. Bibliography#Seacord 05]\] Chapter 4, "Dynamic Memory Management"
\[
[Viega 2005|AA. Bibliography#Viega 05]\] Section 5.2.19, "Using freed memory"
\[
[xorl 2009|AA. Bibliography#xorl 2009]\] ["CVE-2009-1364: LibWMF Pointer Use after free()"|http://xorl.wordpress.com/2009/05/05/cve-2009-1364-libwmf-pointer-use-after-free/]
...
MEM12-C. Consider using a Goto-Chain when leaving a function on error when using and releasing resources 08. Memory Management (MEM) MEM31-C. Free dynamically allocated memory exactly once