Evaluating a pointer—including dereferencing the pointer, using it as an operand of an arithmetic operation, type casting it, and using it as the right-hand side of an assignment—into memory that has been deallocated by a memory management function is undefined behavior 183. Pointers to memory that has been deallocated are called dangling pointers. Accessing a dangling pointer can result in exploitable vulnerabilities.
According to the C Standard, using the value of a pointer that refers to space deallocated by a call to the free() or realloc() function is undefined behavior. (See undefined behavior 177183.)
Reading a pointer to deallocated memory is undefined behavior 183 because the pointer value is indeterminate and might be a trap representation. Fetching a trap representation might perform a hardware trap (but is not required to).
...
Freeing memory multiple times has similar consequences to accessing memory after it is freed. Reading a pointer to deallocated memory is undefined behavior because 183 because the pointer value is indeterminate and might be a trap representation. When reading from or writing to freed memory does not cause a trap, it may corrupt the underlying data structures that manage the heap in a manner that can be exploited to execute arbitrary code. Alternatively, writing to memory after it has been freed might modify memory that has been reallocated.
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 MEM04-C. Beware of zero-length allocations.)
Rule | Severity | Likelihood | Detectable | RepairableRemediation Cost | Priority | Level |
|---|---|---|---|---|---|---|
MEM30-C | High | Likely | No | NoMedium | P18P9 | L1L2 |
Automated Detection
Tool | Version | Checker | Description | |||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Astrée |
| Supported: dangling_pointer_use | Supported Astrée reports all accesses to freed allocated memory. | |||||||||||||||||||||||||||||
| Axivion Bauhaus Suite |
| CertC-MEM30 | Detects memory accesses after its deallocation and double memory deallocations | |||||||||||||||||||||||||||||
| CodeSonar |
| ALLOC.UAF | DYN.ALLOC.UAFUse after free | Dynamic Use After Free|||||||||||||||||||||||||||||
| Compass/ROSE | ||||||||||||||||||||||||||||||||
| 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 Klocwork | ||||||||||||||||||||||||||||||
| Cppcheck |
| Klocwork
| Klocwork
| UFM.DEREF.MIGHT | LDRA tool suite | |||||||||||||||||||||||||||
| Include Page | LDRA_V | LDRA_V | 51 D, 484 S, 112 D | Partially implemented | Parasoft C/C++test | |||||||||||||||||||||||||||
| Include Page | Parasoft_V | Parasoft_V | CERT_C-MEM30-a | Do not use resources that have been freed | Parasoft Insure++ | Runtime analysis | Polyspace Bug Finder | |||||||||||||||||||||||||
| Include Page | Polyspace Bug Finder_V | Polyspace Bug Finder_V | Deallocation of previously deallocated pointer Invalid use of standard library string routine | doubleFree deallocret deallocuse | ||||||||||||||||||||||||||||
| Cppcheck Premium |
| doubleFree deallocret deallocuse | ||||||||||||||||||||||||||||||
| Helix QAC |
| DF4866, DF4867, DF4868, DF4871, DF4872, DF4873 C++3339, C++4303, C++4304 | ||||||||||||||||||||||||||||||
| Klocwork |
| UFM.DEREF.MIGHT UFM.DEREF.MUST UFM.FFM.MIGHT UFM.FFM.MUST UFM.RETURN.MIGHT UFM.RETURN.MUST UFM.USE.MIGHT UFM.USE.MUST | ||||||||||||||||||||||||||||||
| LDRA tool suite |
| 51 D, 484 S, 112 D | Partially implemented | |||||||||||||||||||||||||||||
| Parasoft C/C++test |
| CERT_C-MEM30-a | Do not use resources that have been freed | |||||||||||||||||||||||||||||
| Parasoft Insure++ | Runtime analysis | |||||||||||||||||||||||||||||||
| PC-lint Plus |
| 449, 2434 | Fully supported | |||||||||||||||||||||||||||||
| Polyspace Bug Finder |
| Checks for:
Rule partially covered. | ||||||||||||||||||||||||||||||
| PVS-Studio |
| V586, V774 | ||||||||||||||||||||||||||||||
| Security Reviewer - Static Reviewer |
| CPP_12 | Fully implemented | Memory freed more than once without allocation Standard library string function called with invalid arguments Memory accessed after deallocation Functions which are designed to provide operations on a resource should be called in an appropriate sequence The address of an object with automatic storage shall not be copied to another object that persists after the first object has ceased to exist All resources obtained dynamically by means of Standard Library functions shall be explicitly released A block of memory shall only be freed if it was allocated by means of a Standard Library function | PRQA QA-C++ | |||||||||||||||||||||||||||
| Include Page | cplusplus:PRQA QA-C++_V | cplusplus:PRQA QA-C++_V | 3339, 4303, 4304 | PVS-Studio | | Include Page | | PVS-Studio_V | PVS-Studio_V | V586, V774||||||||||||||||||||||||
| Splint |
| |||||||||||||||||||||||||||||||
| TrustInSoft Analyzer |
| Value analysis (-val)dangling_pointer | Exhaustively verified | ( | See interpreted in the simplified on-line version of the tool.) | ). |
Related Vulnerabilities
VU#623332 describes a double-free vulnerability in the MIT Kerberos 5 function krb5_recvauth().
...
Bibliography
| [ISO/IEC 9899:20112024] | 7.2224.3, "Memory Management Functions" |
| [Kernighan 1988] | Section 7.8.5, "Storage Management" |
| [OWASP Freed Memory] | |
| [MIT 2005] | |
| [Seacord 2013b] | Chapter 4, "Dynamic Memory Management" |
| [Viega 2005] | Section 5.2.19, "Using Freed Memory" |
| [VU#623332] | |
| [xorl 2009] | CVE-2009-1364: LibWMF Pointer Use after free() |
...