...
According to the C Standard, the behavior of a program that uses the value of a pointer that refers to space deallocated by a call to the free()
or realloc()
function is undefined. (See undefined behavior 177 of Annex J.) Similarly, if an object is referred to outside of its lifetime, the behavior is undefined. (See undefined behavior 9 of Annex J.)
...
This example from Brian Kernighan and Dennis Ritchie [Kernighan 1988] shows both the incorrect and correct techniques for deleting items from a linked list. The incorrect solution, clearly marked as wrong in the their book, is bad because p
is freed before the p->next
is executed, so p->next
reads memory that has already been freed.
...
In this noncompliant code example, buff
is written to after it has been freed. These vulnerabilities can be easily exploited to run arbitrary code with the permissions of the vulnerable process and are seldom this obvious. Typically, allocations and frees are far removed, making it difficult to recognize and diagnose these problems.
...
In this noncompliant example (CVE-2009-1364) from libwmf
version 0.2.8.4, the return value of gdRealloc
(a simple wrapper around realloc
which that 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 the C Standard 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].
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 the realloc fails, then we have not lost the * im->clip->list value. */ if (more == 0) return; im->clip->max += 8; } im->clip->list[im->clip->count] = (*rect); im->clip->count++; |
...
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; im->clip->max += 8; im->clip->list = more; } im->clip->list[im->clip->count] = (*rect); im->clip->count++; |
...
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MEM30-C | highHigh | likelyLikely | mediumMedium | P18 | L1 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
|
|
| |||||||
| USE_AFTER_FREE | Can detect the specific instances where memory is deallocated more than once or read/written to the target of a freed pointer | |||||||
5.0 |
|
| |||||||
| UFM.DEREF.MIGHT |
| |||||||
| 51 D | Fully implemented | |||||||
|
|
|
...
CERT C Secure Coding Standard | MEM01-C. Store a new value in pointers immediately after free() |
CERT C++ Secure Coding Standard | MEM30-CPP. Do not access freed memory |
ISO/IEC TR 24772:2013 | Dangling References to Stack Frames [DCM] Dangling Reference to Heap [XYK] |
ISO/IEC TS 17961 (Draft) | Accessing freed memory [accfree] |
MISRA C:2012 | Rule 18.6 (required) |
MITRE CWE | CWE-416, Use after free |
...