CS.LOCRET.RET
Function returns address of local variable
The use of previously-freed memory can have any number of adverse consequences, ranging from the corruption of valid data, to the execution of arbitrary code, depending on the instantiation and timing of the flaw. The simplest way data corruption may occur involves the system's reuse of the freed memory. Use-after-free is a rare situation in C# since it has an internal garbage collector that will not free memory if there are still references to it, but they can still occur in unsafe blocks. The CS.LOCRET checker family finds instances in which an unsafe function provides access to the address of a local variable, outside the scope of the block, leading to issues such as dangling pointer or use-after-free.
The CS.LOCRET.RET checker finds instances in which a function returns the address of a local variable through an expression in the return statement.
Vulnerability and risk
Local variables are allocated on the stack, so when a function returns a pointer to the variable, it's returning a stack address. The address will be invalidated after returning from the function, so access will probably cause unexpected application behavior, typically a program crash.
Use-after-free errors have two common and sometimes overlapping causes:
- Error conditions and other exceptional circumstances.
- Confusion over which part of the program is responsible for freeing the memory.
Vulnerable code example
using System.IO;
namespace Example
{
class Program
{
unsafe static int* aaa()
{
int *aux = stackalloc int[3];
return aux; //@ CS.LOCRET.RET
}
static void Main(string[] args)
{
unsafe {
int *a = aaa(); // 'a' points to freed memory
}
}
}
}
Klocwork reports a CS.LOCRET.RET defect line 9 where function 'aaa' returns the address of local variable 'aux'.
Related checkers
External guidance
Security training
Application security training materials provided by Secure Code Warrior.