You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 21 Next »

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.

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:

int (*log_fn)(const char *, ...) = printf;
/* ... */
log_fn("foo");

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)

Microsoft Windows provides the EncodePointer() and DecodePointer() functions that encrypt and decrypt pointers using a secret that is unique to the given process:

#include <Windows.h>
 
void *log_fn = EncodePointer(printf);
/* ... */
int (*fn)(const char *, ...) = (int (*)(const char *, ...))DecodePointer(log_fn);

fn("foo");

Note that 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. 

Risk Assessment

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

WIN04-C

high

unlikely

low

P9

L2

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

Bibliography

 


  • No labels