Dangling pointers can lead to exploitable double-free and access-freed-memory vulnerabilities. A simple yet effective way to eliminate dangling pointers and avoid many memory related vulnerabilities is to set pointers to NULL after they have been freed, or to another valid object.
Calling free() on a null pointer results in no action being taken by free().
In this non-compliant code example, the type of a message is used to determine how to process the message itself. It is assumed that message_type is an integer and message is a pointer to an array of characters that were allocated dynamically. If message_type equals value_1, the message is processed accordingly. A similar operation occurs when message_type equals value_2. However, if message_type == value_1 evaluates to true and message_type == value_2 also evaluates to true, then message is freed twice, resulting in an error.
char *message;
int message_type;
/* initialize message and message_type */
if (message_type == value_1) {
/* Process message type 1 */
free(message);
}
/* ...*/
if (message_type == value_2) {
/* Process message type 2 */
free(message);
}
|
As stated above, calling free() on a null pointer results in no action being taken by free(). Setting message to NULL after it has been freed eliminates the possibility that the message pointer can be used to free the same memory more than once.
char *message;
int message_type;
/* initialize message and message_type */
if (message_type == value_1) {
/* Process message type 1 */
free(message);
message = NULL;
}
/* ...*/
if (message_type == value_2) {
/* Process message type 2 */
free(message);
message = NULL;
}
|
MEM01-EX1: If a non-static variable goes out of scope immediately following the free(), it is not necessary to clear its value because it is no longer accessible.
void foo(void) {
char *str;
/* ... */
free(str);
return;
}
|
Setting pointers to NULL or to another valid value after memory has been freed is a simple and easily implemented solution for reducing dangling pointers. Dangling pointers can result in freeing memory multiple times or in writing to memory that has already been freed. Both of these problems can lead to an attacker executing arbitrary code with the permissions of the vulnerable process.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
MEM01-A |
high |
unlikely |
low |
P9 |
L2 |
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
\[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\] Section 7.20.3.2, "The free function" \[[ISO/IEC PDTR 24772|AA. C References#ISO/IEC PDTR 24772]\] "DCM Dangling references to stack frames" and "XZH Off-by-one Error" \[[Seacord 05a|AA. C References#Seacord 05]\] Chapter 4, "Dynamic Memory Management" \[[Plakosh 05|AA. C References#Plakosh 05]\] |
MEM00-A. Allocate and free memory in the same module, at the same level of abstraction 08. Memory Management (MEM) MEM02-A. Immediately cast the result of a memory allocation function call into a pointer to the allocated type