If an attacker can overwrite memory containing function pointers, they may be able to execute arbitrary code. To mitigate the effects of such attacks, pointers to functions can be encrypted at runtime on the basis of some characteristics of the execution process so that only a running process will be able to decode them. This is only required for stored function pointers stored to writable memory, including the stack. The Microsoft SDL [Microsoft 2012] recommends encoding long-lived pointers in your code.
Noncompliant Code Example
This noncompliant code example assigns the address of the
printf() function to the
log_fn function pointer, which can be allocated in the stack or data segment:
If a vulnerability exists in this program that allows an attacker to overwrite the
log_fn function pointer, such as a buffer overflow or arbitrary memory write, the attacker may be able to overwrite the value of
printf with the location of an arbitrary function.
Compliant Solution (Windows)
DecodePointer() does not return success or failure. If an attacker has overwritten the pointer contained in
log_fn, the pointer returned will be invalid and cause your application to crash. However, this is preferable to giving an attacker the ability to execute arbitrary code.
|SEI CERT C++ Coding Standard||VOID MSC16-CPP. Consider encrypting function pointers|
|MITRE CWE||CWE-311, Missing encryption of sensitive data|
CWE-319, Cleartext Transmission of Sensitive Information
Microsoft Corporation 2012
Microsoft Security Development Lifecycle (SDL) – version 5.2 Phase 3: Implementation