Start here

Home
About Klocwork
What's new
Fixed issues
Release notes
Installation

Reference

C/C++ checkers
Java checkers
C# checkers
MISRA C 2004 checkers
MISRA C++ 2008 checkers
MISRA C 2012 checkers
MISRA C 2012 checkers with Amendment 1
Commands
Metrics
Troubleshooting
Reference

Product components

C/C++ Integration build analysis
Java Integration build analysis
Desktop analysis
Refactoring
Klocwork Static Code Analysis
Klocwork Code Review
Structure101
Tuning
Custom checkers

Coding environments

Visual Studio
Eclipse for C/C++
Eclipse for Java
IntelliJ IDEA
Other

Administration

Project configuration
Build configuration
Administration
Analysis performance
Server performance
Security/permissions
Licensing
Klocwork Static Code Analysis Web API
Klocwork Code Review Web API

Community

View help online
Visit RogueWave.com
Klocwork Support
Rogue Wave Videos

Legal

Legal information

UFM.FFM.MIGHT

Freed memory may be freed again

If memory is used or referenced after it's been freed, or if it's freed twice, results can be unpredictable. Memory reference problems can cause the use of unexpected values, which in turn can cause programs to crash or execute arbitrary code.

Use-after-free or double-free memory errors typically occur in error conditions or exceptions, unresolved race conditions, or when there's confusion of responsibility for memory between different parts of the program. The UFM checkers find instances of various use-after-free and double-free memory situations in code. The UFM.FFM.MIGHT checker flags situations in which already freed memory may be freed again.

Vulnerability and risk

Memory reference issues can prove to be critical problems. Using previously freed memory can result in corruption of valid data or execution of arbitrary code, depending on the specific situation. When memory is freed, its contents can remain intact and accessible if it isn't reallocated or recycled. The data at the freed location may seem to be valid, but it can change unexpectedly, and cause unintended code behavior.

If memory is allocated to another pointer at some time after it's been freed and the original pointer is used again, it can point to a location in the new allocation. As the data is changed, it can corrupt the validly used memory and result in undefined actions. If a function pointer is overwritten with an address to valid code, a malicious user can cause execution of arbitrary code.

When a program frees the same memory twice, the memory management data structures become corrupted, causing the program to crash or return the same pointer in two later function calls. In this case, an attacker can achieve control over the data that's written into the doubly-allocated memory, which then becomes vulnerable to a buffer overflow attack.

Mitigation and prevention

To avoid memory reference problems:

  • Set pointers to null once they're freed.
  • Make sure global variables are freed only once.
  • Be particularly careful freeing memory in a loop or condiitonal statement, and when you're using the realloc function.
  • Ensure that clean-up routines respect the state of memory allocation.

Vulnerable code example

1  #include <stdlib.h>
2  
3  struct foo {
4      int s1;
5  };
6  
7  int free_freed(void) {
8      int found;
9      int i;
10     struct foo *x;
11     x = (struct foo *) calloc(1, sizeof(struct foo));
12     if (x == NULL)
13        return 0;
14     found = rand();
15     if (found == 0) {
16        i = x->s1;
17        free(x);
18     } else {
19        found = x->s1;
20     }
21     free(x);
22     return 0;
23 }

Klocwork produces a report indicating that the memory pointed by 'x' is freed at line 21, after it was already freed at line 17. Typically, memory is allocated and freed at points further removed in the code than in this example, making it difficult to recognize the situation. In any case, the results of freeing already freed memory can be unpredictable and often critical.