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 |
| 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 | 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 | |||||||
| Cppcheck |
| doubleFree deallocret deallocusePartially implemented | |||||||
| Cppcheck Premium |
| doubleFree deallocret deallocusePartially implemented | |||||||
| 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 | ||||||
| Splint |
| ||||||||
| TrustInSoft Analyzer |
| dangling_pointer | Exhaustively verified (see one compliant and one non-compliant example). |
...